Accessing a channel by reference in sequence


julius228

Recommended Posts

Dear all,

What I am tring to do is to delete the channel history of a long list of channel by a sequence and I was wondering if is possible to access the channel function using a string reference. I try to explain better whit some code:

Private string ChListStr = Channel.ListAll("Main")  //List of all channell
var.CntDel  //counter
While(CntDel<=NumRows(ChListStr))
   ChListStr[CntDel].ClearHistory()
   CntDel++
EndWhile

I tried to execute this, but doesn't work :unsure:

Any suggestion?

Hope to make clear myself,

thanks

Link to comment
Share on other sites

There are several problems:

1) the line:

var.CntDel // counter

does nothing. Use the new declaration and make sure and initialize CntDel:

private CntDel = 0

2) You never initialize CntDel, so the rest won't really work. For() loops are often better for this sort of thing than while:

for (private cntdel = 0, cntdel < NumRows(ChListStr), cntdel++)
   ...
endfor

3) you want to do < NumRows(), not <= NumRows(). DAQFactory, like just about every other programming language, indexes everything from 0, so if you have 5 rows, they'll be numbered 0,1,2,3,4. So you pretty much always want < because there is no row 5.

4) ChListStr is an array of strings, not objects, so you can't do:

ChListStr[CntDel].ClearHistory()

you need to use the execute() function:

execute(ChListStr[CntDel] + ".ClearHistory()")

Change all that and it should work. Here is the final:

Private string ChListStr = Channel.ListAll("Main")  //List of all channell
for (private cntdel = 0, cntdel &lt; NumRows(ChListStr), cntdel++)
   execute(ChListStr[CntDel] + ".ClearHistory()")
endfor

Link to comment
Share on other sites

  • 10 months later...

I'm using about the same code with exception of using () around channel instead of []

Almost all channels have history lengths of 240, persist of 240.

for next loop

execute(channel_list(c_c) +".clearHistory()")

delay(2)

execute("V." +channel_list(c_c) +".clearHistory()")

delay(2)

next

Before I added the delays, channel clearing was hit or miss.

After adding delays, -----

All channels routinely clear, except Real channel_list(5) and (8), sometimes (8) clears.

Sometimes all channels clear.

channels 5 and 8 are named "nHum" and "nVsup" respectively. Another channel has name of "nBar" and clears correctly.

Upping the delays to 3 hasn't seemed to help. Going up further, will cause a ripple affect on the amount of code that would have to be revised.

Any suggestions??????? on what to look for.??????

ek

Link to comment
Share on other sites

Why are you using (). Is channel_list a function? Also I'm assuming you actually have a properly formatted for loop and didn't start in on another language that uses for next loop / next. To help further I need more detail on what channel_list is. I would also consider adding a ? statement before each execute() that displays what is executing, so:

? channel_list(c_c) + "clearHistory()"

Link to comment
Share on other sites

Here's modified code as run just now replace channel_list() with channel_list[]

******************
//	new way of doing weather	  Modified 11 May 09
// 18 Feb 09 set up
// 28 Apr 09   add one to max(chan_count, V_chan_count)
// 01 May 09   add PersitAmount =0  and PersistAmount =Pa()
// 03 May 09 eka  Read the fine print.  Have to do Channel.Restart()
//		  added "V." for Virtual channels
// 08 May 09 eka  delay from 2, to 3 between clears
// 11 May 09 eka  use [] instead of () in Channel_list[]
//
function clear_all_histories()
   // Chan_list() MUST have been called to set our vars
   // 
private c_c =0	   // channel loop counter
private Pa		   // added 01 May 09
private string PaS   // added 01 May 09

	 // most channels we have to do
	  // added 1 to it	 28 Apr 09
private c_l =max((chan_count, V_chan_count)) +1
private string base_time =doubletostr(R_count_last_time)

	  // read current Persist, set to 0, clear history
  for (c_c =0, c_c &lt;=c_l, c_c++)

	  if (c_c &lt;=chan_count)
		 ? c_c	// debug
		 ? 'execute(channel_list[c_c] +".clearHistory()")'

		 execute(channel_list[c_c] +".clearHistory()")
			   // don't ask me why, but needs [] rather than ()

		// execute("Pa[c_c] =" +channel_list(c_c) +".PersistAmount")	 // 01 May 09
		// execute(channel_list(c_c) +".PersistAmount =0")	// 01 May 09
		 //Channel.Restart()
		 delay(4)
		 //  ? Pa[c_c]		// debug
	  endif
			// clear ND also, since we need correct times   18 Feb 09
	  if (c_c &lt;=V_chan_count)
			   // corrected missing "V."	 28 Apr 09
		 execute("V." +V_channel_list[c_c] +".clearHistory()")
		 delay(4)
	  endif

   endfor	  //&lt;&lt;&lt;&lt;&lt;&lt;&lt; end channel loop

//nVsup.ClearHistory()
//nhum.ClearHistory()

//delay(3)
******************************

The above modified code gives SAME results. "nHum" and "nVsup" did not clear.

DF 5.80

Here's the ? statement for channel_list

***********************

? channel_list

{"Temp_K", "Si_Solar", "Se_Blu", "Se_Grn", "Se_Red", "nHum", "iTemp_F", "nBar", "nVsup", "W_dir", "W_count", "R_count"}

************************

As to () rather than []: 30 years of using () for subscripted vars is my only excuse.

ek

Link to comment
Share on other sites

I didn't think the () would make a difference, I just wasn't sure if you were using it to subset or to call a function. DF actually will accept () for subsetting, but that is not guaranteed to continue, and doesn't always work. Its much cleaner to use a different delimiter [].

Anyhow, two things:

1) doing max((chan_count, V_chan_count)) isn't giving you what you think. Its always going to return chan_count. max() takes a single variable, which presumably is an array. What you want is:

max(concat(chan_count,V_chan_count))

the concat() function takes the two scalars and makes them into a 2 element array.

2) I'd actually like to see a ? of:

? channel_list[c_c] +".clearHistory()"

This will tell us exactly what is getting fed to the execute() function. Then you can try manually typing the line into the command alert for the channels that appear not to work.

I assume that absolutely nothing happens to these channels?

Link to comment
Share on other sites

******

? channel_list[] +".clearHistory()"

{"Temp_K.clearHistory()", "Si_Solar.clearHistory()", "Se_Blu.clearHistory()",

"Se_Grn.clearHistory()", "Se_Red.clearHistory()", "nHum.clearHistory()",

"iTemp_F.clearHistory()", "nBar.clearHistory()", "nVsup.clearHistory()",

"W_dir.clearHistory()", "W_count.clearHistory()", "R_count.clearHistory()"}

*******

re max((x,y))

? max((chan_count, V_chan_count))

14

? chan_count

11

? V_chan_count

14

so that construct does return correct values. I think the double (( )) makes it an array???? with two elements.

*****

   add_val ="NaN(),"

	  if (c_c &lt;=chan_count)
		 execute(channel_list(c_c) +
			  ".addvalue(inserttime(" +add_val +base_time +",0))")
	  endif

Above code executes faultlessly (at least for now) in the sequence that "calls" clear_all_histories().

It is in a loop that mirrors the clear history code, but is executed AFTER clearHistory execution.

// check_time_lapse() called by cold_start   Last modified  12 May 09
//************* should only be called if dp &gt;0 ?????
//
//  10 Feb 09 eka	New approach to starting Weather data collection
	  // check_time lapse will find out time of last measurement
	  //	Saves R_count value
	  //	fill missing data points with "ND" or NaN, until next measurement time
	  //	if greater than 1 day has passed,
	  //	Figure out how to check if histories have been exported xxxx
	  //	   then clear ALL histories.
	  // sets global var dp to appropriate value
//  11 Feb 09 eka	max((x,y))	 add parenthses, singles don't work
//			 moved chan_list() call to cold_start_new
//			 revised how we handle rain_count
//  12 Feb 09  Got so didn't bomb
//  21 Feb 09  Add some notes on what to do.  xxxx
//  01 Mar 09  clean up abit  
//  07 Mar 09  modified if &gt;24 hours logic.  Priority to 5 rather than 3, since we want fast
//			 add change day ftp beginseq
//			 Revise for next loop, so add value is Outer loop and channel # is inner
//				should be more efficent
//  20 Mar 09  eka   Comment out all code except Rain stuff
//  23 Apr 09  eka   Try to get to work correctly
//	   Rather than execute, use hard code channel names.
//  24 Apr 09  eka   Corrected add_date_value to STRING
//			 Found out date add value has to be quoted
//  27 Apr 09 eka	Revised for Day_changed flag
//	   Remove all date_time channel stuff
//  28 Apr 09 eka	Correct typo for Day_changed
//	   Revise to do it even if no history
//	   Save and restore some additional channel info
//	   Implement clear_all_histories if Midnite is base time
//  29 Apr 09 eka	Clear V.R_inches counter
//		  if midnite, add limit to floor
//		  Add 25 seconds to time base just in case
//		  Add msg if clearing histories
//		  Add aHistory export stuff
// 01 May 09 eka	 revise so day_changed valid even if add_lim =0
//		  Drop R_date_time and Virtual Date_time assignments
// 02 May 09 eka	 Add provision for update of hour xport files
// 08 May 09 eka  Recalc now time if clear_all_his* done.
//		  Clear R_day_inches if new day
//		  Retry   readable Date_time assignment to V channel
// 12 May 09 eka  Try a clean up of how we do Saves to [0] rather than max[]
//		  Disable Date Time channel execute in channel fill
//
//  ***************	 MUST save V.R_S_T**************
//
//	   Need to modify so can do it if NO history *****
//
function check_time_lapse()

	  // DONE in cold_start_new	AutoStart Routine  find out if we have any history
//global dp =numrows(R_count[])
		 // declare our variables, and set to 0 in case no Histories
		 //  28 Apr 09

Private R_count_save =0
Private R_day_inches =0
Private S_kw_hrs_save =0
Private Rain_Season_total =0
	  // add for hourly update of xport files   02 May 09
Private string hr
Private base_timef


Private now_time =floor(systime())	 // number of seconds
private midnite =floor(systime() /86400) *86400
Global add_lim =floor((now_time -midnite) /360)	// to global 28 Apr 09
global R_count_last_time =midnite

if (dp &gt;0)		   // now if have History set these	28 Apr 09
		 // moved up to here  12 Feb 09, make global for other sequences  18 Feb 09
		 //	add 360	 25 Apr 09
		 //	add 25 seconds, just in case it was slow  29 Apr 09
   R_count_last_time =(floor((R_count.Time[0] +25) /360) *360) +360	
// save our last time
   // we have SOME history
	  // so save R_count[0]
	  // Save more stuff	  28 Apr 09
   R_count_save =R_count[0]	// use only if LJ_reset_done =0
   R_day_inches =V.R_d_inches[0]	   // [0] rather than max []
   S_kw_hrs_save =V.S_kw_hrs[0]		// ditto
	  // end save more stuff  28 Apr 09

		 // was implemented in an R_count* sequence awhile ago, corrected here 12 May 09
   // V.R_S_T.AddValue((R_count_save /100) + 
// max(V.R_S_T[]) already done in R_count* seq

	  //in case was munged
   Rain_Season_total =max(V.R_S_T[])	  // Remove Private 12 May 09

		 // this should give us number of missing readings
   add_lim =floor(((now_time -R_count_last_time) /360))   // all should be integers
endif	   // end conditional have History  28 Apr 09	  
	  // Just in case logic screwy
	  // but day_changed overrides  01 May 09
if ((add_lim +Day_changed) &lt;1)
   return()
endif

//	  // NO ftp, but do midnite here	  07 Mar 09
if (Day_changed !=0)	  //  27 Apr 09 rather than Todays_YYOday !=YYoDay)
	  // add this to history	 01 May 09
  Mote1 ="Day change in `/ time"
  Note2 ="Clear Historys"
  beginexport(aHistory)
  delay(1)

   ? Note1 + ": doing " +Note2	// 29 Apr 09

   clear_all_histories()		 // implement   28 Apr 09
		 // new nowtime if clear_all_histories took long time 08 May 09
   now_time =floor(systime()) 
   add_lim =floor((now_time -midnite) /360)	 // floor added 29 Apr 09
   R_count_last_time =midnite
   R_day_inches =0	  // clear this also   08 May 09
   S_kw_hrs_save =0	 //	and this

   dp =0	   // data points for "today" is zero
endif
	  // check if over 24 hours  revised 07 Mar 09
	  // this should never happen, but be paranoid
//while(add_lim &gt;239)
//   add_limit =add_limit -239
//		 // adjust R_count last time also
//endwhile
	  // Just in case
//if (add_lim &lt;1)
//   return()
//endif
	  // Don't think need this		 12 May 09
//R_count.AddValue(0)	 // so we don't double dip   11 Feb 09

// get our channel list AND chan_count for Real and Virtual GLOBAL vars
//	Global string channel_list =channel.ListAll()
	  // ditto
//	Global String V_channel_list =V.channel.ListAll()
//	global chan_count =0
//	global V_chan_count =0
//   11 Feb 09	chan_list() call NOW done in cold_start_new i.e., Autostart routine.
//		  corrected closing paren on execute statements
//
private c_c =0	   // channel loop counter
private a_c =0	   // add value counter
	  // added one 24 Apr 09
private c_L =max((chan_count, V_chan_count)) +1	  // most channels we have to do

		 //  add time strings	07 Mar 09
Private string add_val
Private time_val =R_count_last_time

//private add_L =0	 // add this many values

? "adding " +doubletostr(add_lim)
//v.test.AddValue(inserttime(NaN(),.Time[0],0))

Global string base_time
Global string add_date_val	   // 24 Apr 09 corrected to string
	  // revised outer loop to add values, rather than channel	07 Mar 09
		// add value loop
for (a_c =0, a_c &lt;=add_lim, a_c++)
	  // revised 02 May 09
   base_time =DoubleToStr(time_val)	 // assign the time to use
   base_timef =time_val

   hr =FormatDateTime("%M", time_val)
		 // the damn thing has to be quoted!!!!!!!  and subtract a second   24 Apr 09
   add_date_val ="'" +FormatDateTime("%m/%d/%y %H%M", (time_val -1)) +"',"

		 // update our Hour files   we hope	 02 May 09
   If (hr =="00")
	 // delay(1)
	 // xport_hour_stuff()
	 // delay(1)
	  ? add_date_val		// debug do hr export here
   endif

   time_val =time_val +360	// increment for next time thru  02 May 09

for (c_c =0, c_c &lt;=c_L, c_c++)
		 // remove all R_date_time &amp; V.date_time code that was commented out 02 May 09
   add_val ="NaN(),"

	  if (c_c &lt;=chan_count)
		 execute(channel_list(c_c) +".addvalue(inserttime(" +add_val +base_time +",0))")
	  endif

			// NOW virtual channels	   keep "nd" &amp; R_S_T ????
	  if (c_c &lt;=V_chan_count)

			   // reinstate Date	08 May 09
		 if (V.channel_list(c_c) =="Date_time")
			add_val ="x"
		 endif

			   // try it	  02 May 09
		 if (V_channel_list(c_c) =="nd")
			add_val ="'ND',"
		 endif

		 if (add_val !="x")	  // disable Date time assign 12 May 09
		// ? "L 134 " +"v." +V_channel_list(c_c) +".addvalue(inserttime(NaN()," +base_time +",0))"
		 execute("V."+V_channel_list(c_c) +".addvalue(inserttime(" +add_val +base_time +",0))")
		 endif

	  endif	//***** end V chan if

	 endfor   //&lt;&lt;&lt;&lt;&lt;&lt;&lt; end channel loop
   // debug ? c_c			   //&lt;&lt;&lt;&lt; end of add times loop
endfor		 //&lt;&lt;&lt; end add loop


   // add for insertTime(	 28 Apr 09
Private fp_base_time =StrToDouble(base_time)

	  // now have this many data points
dp=dp +add_lim
W_count.ClearHistory()
	  // added (insertTime(	  // 28 Apr 09
w_count.AddValue(insertTime(0,fp_base_time,0))
w_count.AddValue(insertTime(0, fp_base_time,0))
	  // just clear the R_inches LJ counter /100   // 29 Apr 09
V.R_inches.AddValue(insertTime(0, fp_base_time,0))
	  // add
Note1 ="`/ time end"
Note2 =" dp &amp; adds " +DoubleTostr(dp) +" " +DoubleToStr(add_lim)
beginexport(aHistory)

	  // Save more stuff	  28 Apr 09
if (LJ_reset_done !=0)
		 R_count_save =0	   // use only if LJ_reset_done =0
endif
		 // NOTE Times will be kewacky  might want to revise???
		 // revised to insertTime	  28 Apr 09
R_count.AddValue(inserttime(R_count_save, fp_base_time,0))
V.R_d_inches.AddValue(inserttime(R_day_inches, fp_base_time,0))
V.S_kw_hrs.AddValue(insertTime(S_kw_hrs_save,fp_base_time,0))
	  // end save more stuff  28 Apr 09
	  // add (insertTime(	 28 Apr 09
V.R_S_T.AddValue(insertTime(Rain_Season_total, fp_base_time,0))	
// restore this to TOP of stack

The only way I can get nHum and nVsup channels to clear reliably is with straight code of:

****

nVsup.ClearHistory()

nhum.ClearHistory()

***

Just ran the code again, and it cleared all histories.

I'll keep you posted.

ek

Link to comment
Share on other sites

OK, forget max().

Main problem is clearing histories. Executed clear history code 3 times since my last post. 3 times did NOT clear the mentioned channels. Real channels 0 thru 11 supposededly executed.

Any suggestions. Or should I just give up and hard code mychannel.clearHistory().

ek

Link to comment
Share on other sites

I actually don't see any problem. It worked just fine for me. That said, I also simplified the system. I turned off all your sequences (since they expected things like paths that I don't have), and set the channels to poll using Timing, and I was able to run the clear_all_histories sequence and have it clear out every time. Now I also eliminated all the delay()'s in that sequence, since they are not needed, and having it means that the sequence takes 50 seconds or so and during that time a bunch of data could reaccumulate (I had a timing of 1). Try simplifying it down on your end as well. PS: I'm on 5.80.

On a different note: you have a user/password for your ftp on the doc. I have deleted the attached file so no one else gets access to it and I believe I'm the only one that downloaded it so you are safe, but be aware that you may want to change your ftp password just in case.

Link to comment
Share on other sites

Damn, forgot all about the passwords. There are two, one in each Ftp_to_*

The whole idea of this, was to get AWAY from timing as suggested by a guru at azeotech in order to totally control timing of data collection. In my code there is NO LJ i/o that I know of until well after the clearHistory sequence.

It maybe due to the slow machine and 512Mbytes of memory I'm using as the development machine. However while that code is running, there are still some CPU ticks and memory available if we can believe TaskManager. Rest of program seems to work AOK.

I am almost at the stage of porting it to the data collection machine, but wanted it thoroughly debugged so as to not interupt data collection. Am trying to solve a problem with NaN getting put out as 100000000000000000000 etc. to my data files and will be ready to port.

The delays were inserted because the histories were not clearing and thought that might solve the problem.

ek

Link to comment
Share on other sites

The only way I've been able to get channel history's to clear is by erasing the Persist files BEFORE starting DF.

NOTE: even if the *.ctl file is loaded in Safe Mode, the persist files are locked by DF, so must be done before loading the *.ctl file.

ek

Link to comment
Share on other sites

*.ctl file xfred to the fast machine.

clearHistory() on fast machine also has problems IF there are Persist data files for the channels.

Only way I can reliably get ALL histories to clear..

Before loading DF *.ctl file, erase all Persist files.

Then execute DF *.ctl file.

Odd note: DF saves my *.ctl file with histories, even when just "save" is selected under "file".

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.