HowTo: Create a Factory Rejects Data Recording system Part 2
Novell Cool Solutions: Feature
By Stomfi
|
Digg This -
Slashdot This
Posted: 2 Mar 2005 |
Learning to use Linux at Home and WorkWelcome to my ongoing series of HowTo articles designed to help Linux newbies get comfortable with Linux. Before trying any of these HowTos, take a few minutes to study the prerequisites so you can hit the ground running. --Stomfi |
This HowTo explains the creation of a turn key system for collecting and analysing factory reject data. See part one.
First a conventional data entry system using collected hand filled out forms will be developed and tested.
Second a factory floor point of origin data entry system using conventional keyboards and screens, will be developed, using the previous data collection files and analysis system.
Third a replacement wireless pocket sized hand held data entry and read out device will be designed to replace conventional keyboards and screens with multi unit base stations for each work area.
Runtime Revolution and the Linux shell tools are the tools used to develop and create this system without requiring any specialised programming skill. Reading HowTos and Linux manuals is as heavy as it gets. When using RunRev you'll find it works best in the Gnome desktop.
The use of Linux has let this system be developed. Any other solution platform would put the cost way out of the reach of the small businesses for whom it was designed.
To simplify things each program module has been developed as a separate RunRev program stack, although RunRev has the ability to combine several stacks into one program. We shall have a look at this aspect at the end of each development.
This is the program stack window which calls the other stacks. It is named "RejCtl"."
In the first part we developed this stack and the stack for the New Rejects Entry Screen. We combined both stacks into a single application.
In this part we shall develop the stacks for the administration buttons. Open the rejctl.rev stack and add the two bottom buttons and the label.
We shall now have a look at the script for the PRODUCTS button.
on mouseUp #This presumes the RejCtl application is saved with the Products stack. go stack "Products" close stack "RejCtl" end mouseUp
Prodadmin is the name of our new stack. Open a completely new stack and give it the name "Products" in the stack property inspector pop up dialog. In the card property inspector give the card the name "ProductAdmin" and give it the label "Product Admin".
This is the Product Admin card.
Place all the fields, buttons and labels as shown.
There are more labels and buttons which are hidden at this point by having their visible property switched off.
This is the Application browser window showing all objects.
The New Fields are label fields which I didn't bother to rename.
As the only instruction is for the SEARCH button, that's what you do.
A search pop up window appears.
As the instruction says you can put any search string in here. Unusual characters will put an error message into the Product List field.
This is the list for "wheel". You can see that the search is not case sensitive.
Using the mouse to select a product from the list, puts its name into the Product Selection field, and puts Yes or No into the four fields under the list.
We can Delete or Modify the selected product and we can Add a new one.
The next picture shows what happens when the Modify button is clicked.
We can modify the name or click the Cancel button to retain the current one.
When the OK or Cancel button is clicked all the hidden fields and buttons appear.
These new buttons allow us to modify the Work Areas for the product. clicking any one allows modification or not. Not clicking them retains what was there already.
This is the pop up that appears when a button is clicked.
After all modifications have been done the user clicks the Work Area Done button.
This deletes the original record and adds the modifications as a new one.
The Messages field shows the final status.
To leave the application the user clicks the x at the top of the screen. I think this is OK for this application, but it may cause problems in the new rejects screen, so we should have a look at putting in a QUIT button and not having the x button.

This is the Basic Properties for the stack. Clicking the Controls button allows us to switch off the functions of the title bar controls.
Don't do this until the very end otherwise you can't move or minimise the window while you are developing.
Add a QUIT button and set the script to:
on mouseUp go stack "RejCtl" close stack "Products" end mouseUp
Now we shall have a look at the scripts that allow all these activities to take place.
Starting from the Card script.
on openCard global SPRODUCT set the invisible of field "WorkAreaMsg" to true set the invisible of button "CAST" to true set the invisible of button "MC" to true set the invisible of button "LIN" to true set the invisible of button "PIM" to true set the invisible of button "DONE" to true global ADDONE global MODDONE put "NO" into ADDONE put "NO" into MODDONE put empty into field "PRODUCT" put empty into field "RESPONSE" put empty into field "PCAST" put empty into field "PLIN" put empty into field "PMC" put empty into field "PPIM" end openCard
This script hides the fields and buttons for the work area input, sets up some global variables and empties all the data fields for a clean page at start up.
The next script is the one for the SEARCH button.
on mouseUp
set the invisible of field "WorkAreaMsg" to true
set the invisible of button "CAST" to true
set the invisible of button "MC" to true
set the invisible of button "LIN" to true
set the invisible of button "PIM" to true
set the invisible of button "DONE" to true
global ADDONE
global MODDONE
put "NO" into ADDONE
put "NO" into MODDONE
put empty into field "PCAST"
put empty into field "PMC"
put empty into field "PLIN"
put empty into field "PPIM"
ask "Enter product name or search pattern"
global SPRODUCT
put it into SPRODUCT
if SPRODUCT <> empty
then
# create a case insensitive pattern matching shell command
put ("grep -i " & SPRODUCT && $HOME & "/frejects/lists/products.
txt | awk -F# '{print $1}'") into mycommand
replace return with empty in mycommand
put the shell of mycommand into field "SLIST"
end if
end mouseUp
The first part of this script repeats the open card functions. Then we use the "ask" command which creates the pop up window. The user response gets put into SPRODUCT. The if test makes sure the rest of the script doesn't get run if the user has either clicked Cancel or OK without entering anything.
The end result of the grep -i is piped to awk to print out only the product names. The resulting list gets put into the Product List.
Clicking a product in this list activates the list script.
on mouseDown
#create a global variable name to hold the whole product line from
the database file
global LongProd
put the selectedText of me into HPROD
#Check in case a blank line was clicked
if HPROD <> empty
then
#Put the product name into the Product Selection field so that
Delete or Modify can use it
put HPROD into field "PRODUCT"
#Fetch the Long Product
put ("grep" && quote & HPROD & quote && $HOME & "/frejects/lists/
products.txt") into onecom
replace return with empty in onecom
put the shell of onecom into LongProd
#Cut up LongProd and put the bits into the relevant fields or
variable names
put ("echo " & LongProd & "|cut -d# -f4") into Castcom
replace return with empty in Castcom
put the shell of Castcom into field "PCAST"
put ("echo " & LongProd & "|cut -d# -f5") into Machcom
replace return with empty in Machcom
put the shell of Machcom into field "PMC"
put ("echo " & LongProd & "|cut -d# -f6") into Lincom
replace return with empty in Lincom
put the shell of Lincom into field "PLIN"
put ("echo " & LongProd & "|cut -d# -f7") into Pimcom
replace return with empty in Pimcom
put the shell of Pimcom into field "PPIM"
#Save existing data when modifying. We are not creating this
bit in this example
global CUST
global CUSTNO
put ("echo " & LongProd & "|cut -d# -f2") into CustName
replace return with empty in CustName
put the shell of CustName into CUST
put ("echo " & LongProd & "| cut -d# -f3") into CustCode
replace return with empty in CustCode
put the shell of CustCode into CUSTNO
end if
end mouseDown
I think this script is self explanatory. The CUST and CUSTNO variables are used in a real application, but not in this example. The fields are there in the database file, so these variables are used to save this info when modifying a product. Another RunRev data entry application is used by accounting staff on an MS windows machine to fill in these two fields in the real world database application.
The next scripts show the DELETE, ADD and MODIFY button actions.
First is the delete button RunRev actions.
on mouseUp
put field "PRODUCT" into DPROD
put ($HOME & "/frejects/bin/delprod.sh " & quote & DPROD & quote)
into DelProd
replace return with empty in DelProd
answer "Really delete this product?" with "Yes" or "No"
put it into SURE
if SURE = "Yes"
then
open process DelProd for read
read from process DelProd until EOF
put it into field "RESPONSE"
close process DelProd
end if
global SPRODUCT
put ("grep -i" && quote & SPRODUCT & quote && $HOME & "/frejects/
lists/products.txt | awk -F# '{print $1}' " ) into mycommand
put the shell of mycommand into field "SLIST"
end mouseUp
Now the delprod.sh shell script.
#!/bin/bash
#delprod.sh product
#
#Change product into RE
PRODUCT=`echo $@`
#DEBUG
#touch $HOME/frejects/tmp/deleted.txt
#echo $PRODUCT >> $HOME/frejects/tmp/deleted.txt
#
#should create a file lock here so no one else can do anything
if [ -e $HOME/frejects/tmp/products.lock ]
then
echo "File in use. Delete aborted"
exit
else
echo "locked" & $HOME/frejects/tmp/products.lock
mv -f $HOME/frejects/lists/products.txt $HOME/frejects/lists/
dproducts.txt
grep -v "$PRODUCT" $HOME/frejects/lists/dproducts.txt > $HOME/
frejects/lists/eproducts.txt
if [ ! -s $HOME/frejects/lists/eproducts.txt ]
then
#didn't work as size is less than 1
mv -f $HOME/frejects/lists/dproducts.txt $HOME/frejects/lists/
products.txt
echo "Problem with delete. Original list restored"
rm -f $HOME/frejects/tmp/products.lock
exit
else
mv -f $HOME/frejects/lists/eproducts.txt $HOME/frejects/lists/
products.txt
fi
echo "Product Deleted"
rm -f $HOME/frejects/tmp/products.lock
fi
exit
Now the add RunRev button script.
on mouseUp
global NCAST
global NMC
global NLIN
global NPIM
global NPROD
global WADONE
global ADDONE
#These make sure that we set the new name and the needed work areas
put empty into NPROD
put "No" into NCAST
put "No" into NMC
put "No" into NLIN
put "No" into NPIM
put "NO" into WADONE
#Ask for a new product name
ask "Enter Full Product Name"
put it into NPROD
#Check that we got a name before we do any actions.
if NPROD <> empty
then
put NPROD into field "PRODUCT"
#This lets the DONE button script know it's a new addition
put "YES" into ADDONE
# SHOW WORKAREA BUTTONS
set the invisible of field "WorkAreaMsg" to false
set the invisible of button "CAST" to false
set the invisible of button "MC" to false
set the invisible of button "LIN" to false
set the invisible of button "PIM" to false
set the invisible of button "DONE" to false
end if
end mouseUp
And lastly the MODIFY button RunRev script.
on mouseUp
global LongProd
global NPROD
#Make sure the N variables are populated with the existing values
put field "PRODUCT" into NPROD
global NCAST
put field "PCAST" into NCAST
global NMC
put field "PMC" into NMC
global NLIN
put field "PLIN" into NLIN
global NPIM
put field "PPIM" into NPIM
#Ask for a modified name or none
ask "Enter Modified Product Name or Cancel for no change"
put it into ENPROD
#Check for a value before acting on it
if ENPROD <> empty
then
put ENPROD into NPROD
put NPROD into field "PRODUCT"
end if
#Let the DONE button know this is a modification
global MODDONE
put "YES" into MODDONE
# SHOW WORKAREA BUTTONS
set the invisible of field "WorkAreaMsg" to false
set the invisible of button "CAST" to false
set the invisible of button "MC" to false
set the invisible of button "LIN" to false
set the invisible of button "PIM" to false
set the invisible of button "DONE" to false
end mouseUp
The next actions are associated with the Work Areas. This is the script for one of the work area buttons. The other scripts are similar with the message and the variable names relevant to the individual work area.
on mouseUp global NCAST answer "Mark Product for Casting Work" with "Yes" or "No" put it into NCAST put it into field "PCAST" end mouseUp
Now for the DONE button which calls the shell scripts that add to or modify the database file.
on mouseUp
#Declare all the global variables
global ADDONE
global MODDONE
global NPROD
global NCAST
global NMC
global NLIN
global NPIM
global LongProd
global CUST
global CUSTNO
#Find out whether one of the DONE variables have been set to YES
before taking any action
if ADDONE = "YES" or MODDONE = "YES"
then
if ADDONE = "YES"
then
put "Adding Product" into field "RESPONSE"
global WADONE
put "DONE" into WADONE
#Create the new product database line
put (NPROD & "#" & CUST & "#" & CUSTNO & "#" & NCAST & "#" &
NMC & "#" & NLIN & "#" & NPIM) into NewPLine
replace return with empty in NewPLine
put ($HOME & "/frejects/bin/newprod.sh" && NewPLine) into
NewProd
replace return with empty in NewProd
#Do the new product shell script and read the response
open process NewProd for read
read from process NewProd until EOF
put it into field "RESPONSE"
close process NewProd
#Reset the ADDONE variable to NO
put "NO" into ADDONE
end if
if MODDONE = "YES"
then
put "Modifying Product" into field "RESPONSE"
#Create the Modified product database line
put (NPROD & "#" & CUST & "#" & CUSTNO & "#" & NCAST & "#" &
NMC & "#" & NLIN & "#" & NPIM) into MPROD
replace return with empty in MPROD
#Set up the add and delete shell script commands
put ($HOME & "/frejects/bin/newprod.sh " & MPROD) into NewMod
replace return with empty in NewMod
put ($HOME & "/frejects/bin/delprod.sh " & LongProd) into DelMod
replace return with empty in DelMod
#Delete the original product line
open process DelMod for read
read from process DelMod until EOF
put it into field "RESPONSE"
close process DelMod
#There really should be an if check based on a success message
from DelMod before NewMod is run
#I'll leave that for the clever one to implement.
#Add the newly modified product line
open process NewMod for read
read from process NewMod until EOF
put it into field "RESPONSE"
close process NewMod
#Reset the MODDONE variable to NO
put "NO" into MODDONE
end if
#Search and list the new product name
put ("echo" && quote & NPROD & quote & "|awk '{print $1}'")
into SearchName
replace return with empty in SearchName
put the shell of SearchName into SearchProd
put ("grep -i" && quote & SearchProd & quote && $HOME & "/frejects
/lists/products.txt|awk -F# '{print $1}'") into pshell
replace return with empty in pshell
put the shell of pshell into field "SLIST"
#Hide the work area messages and buttons
set the invisible of field "WorkAreaMsg" to true
set the invisible of button "CAST" to true
set the invisible of button "MC" to true
set the invisible of button "LIN" to true
set the invisible of button "PIM" to true
#We can't hide the DONE button because we are still using it
#Clever users may figure out how to do this
end if
end mouseUp
This is the newprod.sh shell script.
#!/bin/bash
#newprod.sh productfileline
#
#should create a file lock here so no one else can
#add or delete to the product list
if [ -e $HOME/frejects/tmp/products.lock ]
then
echo "File in use. Add new aborted"
exit
else
echo "locked" > $HOME/frejects/tmp/products.lock
#Copy file to process file
cp -f $HOME/frejects/lists/products.txt $HOME/frejects/lists/
aproducts.txt
#echo newline and product into file
#DEBUG
#echo "$@" >> $HOME/frejects/tmp/newproducts.txt
#END DEBUG
echo -e "\n$@" >> $HOME/frejects/lists/aproducts.txt
#Sort file
sort -f -o $HOME/frejects/lists/bproducts.txt $HOME/frejects/lists/
aproducts.txt
#get rid of any duplicates
uniq $HOME/frejects/lists/bproducts.txt > $HOME/frejects/lists/
cproducts.txt
#get rid of blank lines
sed -e /^$/d $HOME/frejects/lists/cproducts.txt > $HOME/frejects/
lists/dproducts.txt
#copy process file back to production list
cp -f $HOME/frejects/lists/dproducts.txt $HOME/frejects/lists/
products.txt
echo "Product Added"
rm -f $HOME/frejects/tmp/products.lock
fi
exit
Don't forget to add the QUIT button as shown above. Finally change the window decoration functions as shown.
Open the new rejects stack and do these same things for it, creating a QUIT button with its script as:
on mouseUp go stack "RejCtl" close stack "NewRejects" end mouseUp
and then change the NewRejects button script in the RejCtl stack to this.
on mouseUp
#This presumes the RejCtl application is saved with the Products
stack included.
go stack "NewRejects"
close stack "RejCtl"
end mouseUp
All that's left to do is to compile the project. There are three stacks now. Open the RejCtl stack and save and close all other stacks. In the file menu select Distribution Settings. In the Stacks tab, add the newrejects.rev and the products.rev stacks. Click the x to quit this window. In the File menu select Build as Standalone distribution and build it in the frejects bin directory. The program will be what you called it and its folder will include the newrejects.rev and the products.rev files. When you run the program it will open these files when you click the relevant button, and close the RejCtl stack. When you quit the rejects or products stacks it will reopen the RejCtl stack. The file is only 2M plus the small amount for the .rev files.
In the three stacks and their associated shell scripts, you have developed a real world application which can be modified for use in an actual business you know. The one I built is being used as you read this. The cost for the hardware was $0 as a disused P2 was used. The cost of the software was $11 for a magazine with KNOPPIX which was installed on the hard drive, and $199 for RunRev. The development cost was $300 as it was done by two factory workers at a Linux end user course as a real world project. A reinstall CD was also created to minimise maintenance. Total cost $510. total time 10 man days.
Since all data is backed up to the corporate MS environment, the worst case scenario is reinstalling the system on another inexpensive PC.
Quotes from MS centric sources for the same system functions were $40,000 and $15,000, with at least 6 month development time. So the small business achieved savings of at least $14,490, and had their system operational within a month. Viva Linux users!
In the next part of this how to we shall build the Operators admin and Charting stacks and the shell scripts that do the processing, and add these to our RejCtl application. This will finish the first aim of this HowTo.
Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

Learning to use Linux at Home and Work