RJE Posted July 4, 2009 Share Posted July 4, 2009 Hello I Link to comment Share on other sites More sharing options...
AzeoTech Posted July 4, 2009 Share Posted July 4, 2009 I'm not completely sure that DF Channels is going to be your best bet, at least not initially. First try and get stuff into variables and use sequences. Then you can work on channels. As for getting the data, the transmit is easy, just use: device.mydevice.write("$>2800008C#") Presumably you would generate that string dynamically based on the actual id. Reading is not much harder. Fortunately it appears they use the # as an end of line delimiter, so you can get a line just by doing: private datain = device.mydevice.readuntil(35) where 35 is the ascii code for # Once you get the line, you can use the parse() function to split it out. It appears each parameter is separated by a space: datain = parse(datain, -1, " ") This will make datain be an array of strings. If there is no data, then numrows(datain) will be 1, so that's an easy check. Otherwise, you can parse through each response with a simple loop: for (private i = 1, i < numrows(datain), i++) // do something with datain[i] endfor When I say do something, I mean use the various string functions of DAQFactory to parse a particular item. As an example, if you received this line: $<2800! C05C05 CONCON9B# once you did the parse(): datain[0] would = "$<2800!" datain[1] would = "C05C05" datain[2] would = "CONCON9B" The # would actually not be in the string read (datain before the parse) since it was the end of line delimiter. Link to comment Share on other sites More sharing options...
RJE Posted July 6, 2009 Author Share Posted July 6, 2009 Thanks Good advice on the channels, get data into variables first. You pointed me in the right direction and with enough info to be dangerous. Don't blame me if your lights turn off and on. if (SysTime() < 16h) // if its not 4pm yet WaitUntil(16h) // wait until 4pm else WaitUntil(16h+86400) // otherwise, wait until 4pm tomorrow endif while (1) do something... WaitUntil(16h + 86400) // wait until 4pm tomorrow endwhile This code snip from the manual to do something everyday at 4pm, for 4:15pm you would use: if (SysTime() < 16h15m rje Link to comment Share on other sites More sharing options...
AzeoTech Posted July 7, 2009 Share Posted July 7, 2009 Yes, but personally, I use something more like this: private nexttime = 16h15m if (nexttime < systime()) nexttime += 86400 endif while (1) waituntil(nexttime) // do something nexttime += 86400 endwhile And in actual fact, I would do this: private nexttime = 16h15m if (nexttime < systime()) nexttime += 86400 endif while (1) if (systime() > nexttime) // do something nexttime += 86400 endif delay(1) endwhile Its actually not quite as efficient this second way since the script loops every second, but it gives you more flexibility and allows you to do other stuff in the same loop while waiting. A personal preference really. Link to comment Share on other sites More sharing options...
RJE Posted July 8, 2009 Author Share Posted July 8, 2009 I don't think I'm following the while (1), could you explain how it works? while (1) waituntil(nexttime) // do something nexttime += 86400 endwhile Thanks rje Link to comment Share on other sites More sharing options...
AzeoTech Posted July 8, 2009 Share Posted July 8, 2009 In DAQFactory, like many other programming languages, non-zero values are consider "true" and 0 is considered "false". 1 is typically used for "true", so while(1) means loop forever, since 1 is always true. The script thus loops forever, doing something at 4:15 every day. Link to comment Share on other sites More sharing options...
RJE Posted July 21, 2009 Author Share Posted July 21, 2009 Ok, I understand what while (1) means. private nexttime = 16h15m if (nexttime < systime()) nexttime += 86400 endif while (1) if (systime() > nexttime) // do something nexttime += 86400 endif delay(1) endwhile For this code, after the endwhile would it return to the while (1) or would it return to the if? This code works fine for a single 'do something' at a certain time but how to deal with 20 individual 'do somethings' all at various times. This is where I'm locking up. Thanks rje Link to comment Share on other sites More sharing options...
AzeoTech Posted July 21, 2009 Share Posted July 21, 2009 It would return to the while(1). 20 different do somethings? Just create 20 different sequences. That is the easy solution, although not very elegant. There are more elegant solutions, but creating 20 sequences isn't that bad and is easier to understand if you are just starting out. Link to comment Share on other sites More sharing options...
RJE Posted August 24, 2009 Author Share Posted August 24, 2009 OK, I have most things working except one and my forehead is bruised and bloodied from banging it off the brick wall. The X10 unit I poll can store multiple codes it receives, so when polled I can get this: Tx: $>2800008C# Rx: $<2800! C04C04 COFFCOFF C04C04 CONCON C04C04 COFFCOFF C04C04 CONCON7B# Parsing it out is not a problem but dealing with the last parsed data is. The last parsed "packet" always has the checksum value and the delimiter #. In the above example how would I drop the '7B#' off the last parsed data? Remember the parsed data can vary in length. I could post my code attempts but none have worked. Any X10 transmission from within my home, the last parsed 'packet' should always be xONxON7B# or xOFFxOFF7B#. With x being A - Z and the checksum 7B will also vary depending on the whole packet. Thanks Link to comment Share on other sites More sharing options...
AzeoTech Posted August 25, 2009 Share Posted August 25, 2009 Just use the left() function to trim the last 3 characters: x = left(x, getlength(x) - 3) where x is your last "packet" Link to comment Share on other sites More sharing options...
RJE Posted August 25, 2009 Author Share Posted August 25, 2009 I'm on the right track but here's where I'm going wrong. Data_In = Device.TI103.ReadUntil(35) // What DataIn contains - $<2800! C04C04 COFFCOFF C04C04 CONCON C04C04 COFFCOFF C04C04 CONCON7B# Data = Parse(DataIn, -1, " ") //This should give me Data[0], Data[1]......Data[8] right? private i = NumRows(Data) //This to get the last Data[?} number, right? So far all works but when I try to do anything on Data I get the Error saying a parameter is empty. So close yet so far! Link to comment Share on other sites More sharing options...
RJE Posted August 25, 2009 Author Share Posted August 25, 2009 Never mind, found it. 0 indexing, thus subtract 1 from NumRows(Data). Sheeesh! Link to comment Share on other sites More sharing options...
RJE Posted September 6, 2009 Author Share Posted September 6, 2009 Ok, #63, this is what I have working, may not be pretty but it is functional. // test to check incoming X10 global C06 = 0 //set to zero as per private variables private string Data_In private string Data private C06x = 0 //set variables to zero, will be done in a first run sequence later private C06ON = 0 private C06OFF = 0 while (1) Device.TI103.Purge() Device.TI103.Write ("$>2800008C#") //request data command Data_In = Device.TI103.ReadUntil(35) Data = parse(Data_In, -1, " ") private Packet = (NumRows(Data)) if (Packet >> 1) // parsed data has to be longer than 1 if any data on power line has been received private Length = NumRows(Data) // get total length of data received private i = Length - 1 // subtract 1 because of 0 indexing Data[i] = Left(Data[i], GetLength(Data[i]) - 3) // strip off check sum and delimiter on last parsed data for (private p = 1, p < numrows(Data), p++) switch //compare to see what we got case (Data[p] == "C06C06") C06x = 2 case (Data[p] == "CONCON") C06ON = 4 case (Data[p] == "COFFCOFF") C06OFF = 6 endcase endfor Packet = 0 //clear packet count for next read endif if ((C06x + C06ON + C06OFF) == 6) //C06C06 CONCON is received C06 = 1 //set master global variable C06x = 0 C06ON = 0 private string C06_1 = FormatDateTime("C06 ON: %c", SysTime()) //need to log this to a file, further work needed ? C06_1 //out to command window endif if ((C06x + C06ON + C06OFF) == 8) //C06C06 COFFCOFF is received C06 = 0 //set master global variable C06x = 0 C06OFF = 0 private string C06_0 = FormatDateTime("C06 OFF: %c", SysTime()) ? C06_0 //out to command window endif Delay(2) endwhile This is tested with only 1 X10 code on the powerline, C06 ON & C06 OFF but in real life I will have to check for about 30 X10 codes. Question is, before I enter code for a few days is the case/switch the right thing to be using? Thanks rje Link to comment Share on other sites More sharing options...
AzeoTech Posted September 6, 2009 Share Posted September 6, 2009 Switch case should be used in place of if/elseif type of structure where only one of the items will ever be true (or at least only one will ever want to execute). Also: if (Packet >> 1) is incorrect. >> means shift right, so this if will evaluate to true whenever packet > 1, which just happens to work out in your case, but its not really what you meant. You want just: if (packet > 1) Link to comment Share on other sites More sharing options...
RJE Posted September 9, 2009 Author Share Posted September 9, 2009 Not sure if I understand your answer. I'll never know what I will receive but assuming I only receive this: C04C04 & COFFCOFF (afer parsing). Now I must compare these 2 to a list to see if anything should be done. From your answer I gather I should use mutiple if/elseif statements and not case/switch. Roger on the (packet > 1). Thanks Link to comment Share on other sites More sharing options...
AzeoTech Posted September 10, 2009 Share Posted September 10, 2009 No, switch/case replaces if/elseif. It executes the first case() that matches. So, lets say you had: switch case (x > 3) do 1st thing case (x > 1) do 2nd thing endcase If x > 3, then only the 1st thing executes. The 2nd thing will only execute if x > 1 but <= 3. If you need it to do both if x > 3, then you need two separate ifs: if (x > 3) do 1st thing endif if (x > 1) do 2nd thing endif See the difference? The switch/case is actually the same as: if (x > 3) do 1st thing else if (x > 1) do 2nd thing endif endif but as you can imagine, if you had more than a couple items, the if/else if structure would become hard to read with all the else, if, endifs and proper indentation. The switch/case is much clearer. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.