IX: Python DAC FFQueue FFQ (173.html)

WARNING: THIS DAC FFQueue SYSTEM IS IN EARLY DEVELOPMENT MODE

Keywords:
ICH180RR "Raspberry Pi" Raspberry Pi Python "Raspberry Zero 2W" "Fast Food Orders" "DAC Requests Queue" "vcgencmd measure_temp" "nsxio Pictures/alarm.png" nsxio vcgencmd DA&C DAC "Data Acquisition & Control" FFQueue "FFQueue system" FFQueue FFQ oscommand inputWto D@CC "Raspberry Pi Pico" IXQ "IXQueue system"

/KeywordsEnd


(To enlarge .....Click it)
thumb: IXimage.jpg
IX or DC (IX by DC) or "|><"


This software will become part of the IX family of software.

Click on the photo to enlarge it.

thumb: IMG_5180.jfif

Raspberry Pi Zero 2W in its case

Introduction

This concept of treating Acquisition and Control (AandC) like a simple kiosk with an order queue is a novel way to handle Process Control. Python's powerful Queue mechanism greatly simplifies the handling of multiple simultaneous orders. This queue was originally named FFQ (Fast Food Queue) but the author has decided that the name will be changed to IXQ when the concept is included in the IX Family of Software (process control code modules). For more information about the IX Family of Software see Article 196 named "prepIX" in Source 02.

Requesting an Acquisition or Control action from a "Control System" is often found to be complicated and confusing. This simple FFQueue system treats each request like requesting an order from a Fast Food Restaurant Kiosk. The actual order queue is defined as the variable FFQ. Each order is carefully formed in a RequestStr. A typical order might be the string "AcpuTemp" to request that the CPU temperature be acquired (measured). The order is requested in a single statement. The FFQueue system can even be used in Python Interpreter mode as shown below:
<$ FFQ= { }                           # defines the Queue.
<$ RequestStr = "AprocTemp"
<$ TimeCancel = TimeNow+30
<$ OrderStr = FFRequest(FFQ, RequestStr,TimeCancel)
<$ print OrderStr                     # will print 30F
The Order can be returned and placed in the variable named OrderStr. For example the string returned might be a temperature like "30F" The function described below will return the RequestStr ":" OrderStr. For example: "AprocTemp:30F".

This may seem moot, but this FFQueue system allows for actions that are not immediately completed. However if the action takes too long to be completed, the requested action is cancelled. For example, if the operator takes too long to acknowledge/dismiss a situation, the system can ignore the absense of a reply. Sometimes, a requested acquisition or control action takes too long. These situations can produce an Error/Warning message instead of causing the system to "hang".

The author believes that this system can be used with the Maker Pi Pico board combined with MMBasic running on the Pico.

The FFRequest function in the FFQueue system is defined as follows:
def FFRequest(FFQ, RequestStr, LatestTime)
	OrderNumberStr = "BUSY"
	while OrderNumberStr == "BUSY":
		#latestTimeWithoutCancellingStr = LatestTime
		# eg LatestTime=TimeNow+120 "seconds" 
		OrderNumberStr = FFKiosk(FFQ, RequestStr, LatestTime)
		# FFKiosk will return an OrderNumberStr
		if OrderNumberStr == "OOS":
			FFErrorReport("Error: Out Of Service for Request:"+RequestStr)
			return RequestStr+":OOS"
		#end if
		if OrderNumberStr== "BUSY":
			sleep (2)     #sleep 2 seconds
		#end if
		# if the while code stops looping, OrderNumberStr will contain an actual number in string format
		# and the request will have been added to the FFQ.
	#wend
	#an order # was returned
	StatusStr="N"
	while StatusStr == "N":
		StatusStr = FFStatus(FFQ, OrderNUmberStr)
		# returns "N",       Not yet complete
		#	  "Y"         Yes . . . complete
		#            "L"         Log of completed orders
		#        or "X"        X indicates that the order timed out
		if StatusStr == "X":
			FFErrorReport("Error: Cancelled after TimeOut for:"; RequestSt, OrderNumberStr)
			return RequestStr+":X"
		#end if
		if StatusStr == "N":
			sleep (2)     #sleep 2 seconds
		#end if
		if StatusStr == "L":
			FFErrorReport("Warning: Already Read & Logged:"; RequestSt, OrderNumberStr)
		#end if
		# while loop stops looping if "L" or "Y"
	#wend
	# at this point StatusStr is "L" or "Y"
	#        both cases will return the ResultStr
	#        but the "L" case posted a warning 
	ResultStr = FFResult(FFQ,OrderNumberStr)
	RequestAndResultStr = RequestStr+":"+ResultStr
	FFLog(FFQ, OrderNumberStr+":"+RequestAndResultStr)
	return RequestAndResultStr
#end function
Notice that the request is placed in the FFQ and is identified by an OrderNumberStr. But the OrderNumberStr is not normally seen by the program that calls the FFRequest function.

Experienced programmers will understand that more than one "thread" can enter the FFRequest function, each such "thread" can pause at the "sleep (2)". This permits the simultaneous use of this re-entrant Python FFQueue system for many concurrent A/C requests. Inexperienced programmers might refer to Source 03 which is a simplified queue example. Serious programmers might wish to study the Python queue methodology described in Source 04. Such programmers will understand that each FFQ record contains:

OrderNumberStr: TimeRequest, RequestStr, LatestTime, ResultStr, Flag, TimeLogged

The Flag is "Y" if the order is complete, "N" if pending, "X" if cancelled. The various software modules which comprise the FFRequest system are:
                Functions already coded are preceded by a "Y"
Y FFBackup	making a backup of the FFQ to a text file.
Y FFControl	written by the user (see example below)
Y FFErrorReport	an error handler
Y FFflag		returns the value of the current flag in the FFQ record
  FFKiosk	the placing of the Order request (at the Kiosk)
  FFLatestTime	returns the LatestTime in the FFQ record
Y FFLog		every request & result is timestamped and logged in the FFQueue log file
Y FFRequest	the main request function that is invoked by the user
Y FFRestore	restoring the FFQ from a text file at start-up
  FFResult	returns the current result of the requested Order
  FFSave		saving the FFQ to a text file at program shut-down
  FFSetflag	sets the pending lag in the FFQ record to either "Y" or "N" or "X"
  FFSetResult	sets the ResultStr in the FFQ record
  FFStatus	the status of the next pending Order
Y FFTimeMsec	returns the time in seconds with 3 decimal digits

Actual Requests and Results are defined in the user-written FFControl function

An example of an Acquisition action and a Control action are presented in the sample FFControl function definition shown below. The Acquisition Action is the reading of the temperature of the processor chip in the Raspberry Pi which is done by the Terminal command:

  vcgencmd measure_temp

and an example of a Control action is the displaying of an Alarm situation
by showing the word ALARM in a window on the display using the following
Terminal command which is an nsxio statement:

  nsxio Pictures/alarm.png

It may be necessary to install nsxio using the Raspberry Add/Remove Software module.

  inputWto("message",waitTimeOutInterval)

The inputWto sends a message to the operator then waits for a reply to be input.
It sleeps while waiting for the TimeOut interval, returning a second paramet = True if timed out.
If the operator replies within the TimeOut interval, the first parameter is the reply and second parameter = False
The two Acquisition and Control requests shown above do not require any special electronics. Therefore they can be tested by any programmer using Python on a Raspberry Pi. The FFControl function for these two requests is shown below. The user of the FFQueue system must program his/her own FFControl function by adding and defining more actions.
def FFControl (FFQ, RequestStr)
	select case RequestStr:
		"Calarm"
                                    # announce & display an alarm
			oscommand("nsxio Pictures/alarm.png")
                                    # set Pending Flag to "Y"

			# ask if dismissed, Waiting For TimeOut of 20 sec (ie FFLatestTime - TimeNow)
			# the user should dismiss the alarm by its latest time
                                    (textInput,isTimedOut) = inputWto("Has the Alarm been dismissed?",FFLatestTime(FFQ,OrderNumberStr)-TimeNow)
			# the system will sleep during the previous statement until either operator acknowlegment or timeout
			# the actual text of any reply is discarded
			if isTimedOut :
				# prepare to announce the non-Acknowledgement
				ResultStr = "Cancelled after TimeOut"
				# cancel this order
                                    	FFsetflag(OrderNumberStr,"X")
			else:
				# valid announcement of alarm and its Dismissal
				ResultStr = "Alarm announced & dismissed"
				# end this order normally
                                    	FFsetflag(OrderNumberStr,"N")
			#if end
		"AprocTemp"
			FFSetflag(FFQ,OrderNumberStr,"Y")
			ResultStr = oscommand("vcgencmd measure_temp")
		"Ahumidity"
			FFSetflag(FFQ,OrderNumberStr,"Y")
			ResultStr = "OOS"  # Out Of Service
		else:
			FFSetflag(FFQ,OrderNumberStr,"Y")
			ResultStr = "AC action not defined"
	#select end
	FFSetResultStr(FFQ,ResultStr)
	return ResultStr
#end function

def FFErrorReport(msg)
	print("EROR:"+msg)
	return
#def end
def FFLog(msg)
	return
#def end
An example of the use of the FFRequest for one Acquistion and one Control action (and a bad request and an Out Of Service action) is shown in the program below. The oscommand used above is a simple Python function that invokes a Terminal command and returns the result.
progName = "DAC example"
print progName
#  FFQ must be defined here
FFQ = { }
timePlus30Str =timenow + 30   # i.e. in 30 seconds 
print FFRequest("AprocTemp", timePlus30Str)
print FFRequest("AprocTemp", timePlus30Str)

timePlus30Str =timenow + 30   # i.e. in 30 seconds 
print FFRequest("Calarm", timePlus30)

timePlus30Str =timenow + 30   # i.e. in 30 seconds 
print FFRequest("Badrequest,timePlus30)

timePlus30Str =timenow + 30   # i.e. in 30 seconds 
print FFRequest("Areadhumidity",timePlus30)
print "end of "+ progName
end

Results of the above "AC example" program

DAC example
AprocTemp:30F
AprocTemp:30F
Calarm:Alarm announced & dismissed
Badrequest:AC action not defined
Error: Out Of Service for Request:Areadhumidity
end of DAC example
The error message shown below will occur if the letter Q is not typed within 30 seconds to dismiss the alarm notification.

Error: Cancelled after TimeOut for:Calarm

Note that the above programs have not yet been fully programmed nor tested as of Feb 19 2022

End of Article (Sources follow)

This article, by D@CC is of course, a work-in-progress as of 2022BFeb19.

Sources

Video Sources

Video Source 01:www RPi Pico with an SDcard (using MicroPython) by DigiKey on 2021GJul 26

Web Sources

Web Source S172:01:www Raspberry Pi Dumb Terminal (VT100) by Tymkrs on Sept 14 2015
Web Source S172:02:www IT: prepIX (196.html) by D@CC on 2023 E May 16
Web Source S172:03:www Simplified Python Queue Example byArchana Vaidya on 2018 E May 13
Web Source S172:04:www queue- A synchronized queue class by python docs before 2023 E May 16

/SourcesEnd



WebMaster: Ye Old King Cole

There is a way to "google" any of the part-numbers, words or phrases in all of the author's articles. This "google-like" search limits itself ONLY to his articles. Just go to the top of "Articles by Old King Cole" and look for the "search" input box named "freefind".

Click here to return to Articles by Old King Cole

Date Written: 2022 B Feb 18
Last Updated: 2024 D Apr 17

All rights reserved 2024 by © ICH180RR

Backed Up On: 2022 B Feb 18 as 173_2022BFeb18.html
Should edit using EditPad Lite 8 using Consolas (or Courier New) Font (monospaced)

/173.html