Dynacard graphing, Part 2

So I got my Weatherford pump off controller connected to Ignition and am successfully pulling in Dynacard data. I have been successful in partially graphing out the points on a paintable canvas, but have run into a snag. The dynacard tag is a string array which I using a Split function on to parse it out into a dataset. The dataset is 1102Rx1C in size. The first ten rows contain dynacard information (format, data length, etc), leaving 1092 data points. Using the paintable canvas I started with this short script to pull data from the dataset and assign it to variables:


g = event.graphics

data = event.source.parent.test_set
a1 = int(data.getValueAt(10,0))
a2 = int(data.getValueAt(11,0))

kronk = GeneralPath()
kronk.moveTo(10,10)
kronk.lineTo(a1,a2)
kronk.closePath()
g.draw(kronk)

 Naturally I had more lines of code generating variables for b1,b2,c1,c2 etc. At first it seemed very successful until I tried to dump all 1092 data points into the script, in which case I got an error. Looking the error up via Bing I found out that I was exceeding some 64k buffer with the amount of code I was using. I am somewhat new to python coding, and tend to find the most obvious and simple solutions using the help file included with Ignition and various web searches.
 Anyway, I am asking for any ideas or solutions to this issue. I had considered using a FOR loop, but I don't know 1)how to jump past the first ten rows of the dataset and, 2)use each PAIR of coordinates appropriately through the FOR statement.
 I may not be explaining this appropriately, so if you need further clarification please ask. Thanks for any help in advance.

Try something like this (using range):

#use this to skip the first 10 items
OFFSET = 10

g = event.graphics

data = event.source.parent.test_set

#use this code to figure out the length of your set
TOTAL = len(system.dataset.toPyDataSet(data))

#this skips the first 10 rows and assumes each two following rows are a1 followed by a2 on the next row
for i in range(OFFSET, TOTAL, 2):
	a1 = int(data.getValueAt(i,0))
	a2 = int(data.getValueAt(i + 1,0))

	kronk = GeneralPath()
	kronk.moveTo(10,10)
	kronk.lineTo(a1,a2)
	kronk.closePath()
	g.draw(kronk)

Generates error:

ValueError: invalid literal for int() with base 10: 859]

Sounds like one of your values does not easily convert to int(). You can skip that point by putting a try except block around the code:

...
   try:
      a1 = int(data.getValueAt(i,0))
      a2 = int(data.getValueAt(i + 1,0))
   except:
      print "Error in row ", i
...

Here’s a sample window

EDIT: To be honest I’m not 100% certain what the output is supposed to look like-- such as you were needing the line at the end to close the path (the last move I put in there effectively eliminates it Feel free to modify it to your needs). But the loop works! :laughing:

[quote=“adamaustin”]Sounds like one of your values does not easily convert to int(). You can skip that point by putting a try except block around the code:

... try: a1 = int(data.getValueAt(i,0)) a2 = int(data.getValueAt(i + 1,0)) except: print "Error in row ", i ... [/quote]
+1

this is what it should look like

The problem is that the last row has a bracket in it. The data comes across from the controller as a string array and looks like this:

[3,10,1092…9,75,4]

When using SPLIT to parse the data out into a dataset the first row has a string value of “[3” and the last row has a string value of “4]”. Naturally the bracket does not translate into an integer value. The first ten rows are skipped, so the first bracket doesn’t cause a problem. I fixed the issue by adding another variable called STOP, equal to the length minus a few rows and set that to the stop value of the range function and it came up just fine. In fact I am now seeing the data graphed out properly (well, 99%).

offset = 10
data = event.source.parent.test_set
total = len(system.dataset.toPyDataSet(data))
stop = total - 12

kronk = GeneralPath()
kronk.moveTo(0,0)
for i in range(offset, stop, 2):
	a1=int(data.getValueAt(i,0))
	a2=int(data.getValueAt(i + 1,0))
	kronk.lineTo(a1,a2)

Pending a few adjustments and some additional graphics, I think this is it! Thanks!

This is what I am now seeing:

Not perfect, but with a little adjustment it should be good. It’s a lot better than what I started with, and thanks again for the help!

[quote=“pjgonzales”]The problem is that the last row has a bracket in it. The data comes across from the controller as a string array and looks like this:

[3,10,1092…9,75,4]

When using SPLIT to parse the data out into a dataset the first row has a string value of “[3” and the last row has a string value of “4]”. Naturally the bracket does not translate into an integer value…[/quote]

Ah! Easy enough fix for you.

Where you perform the split, you can use a slice to peel off the front and end brackets:
Here’s some samples of splits and slices you can try out in the script playground.

a='[20,25,30,60,40,70,30,70,20,50]' x=a[1:-1] y=a.split(',') z=a[1:-1].split(',') print x print y print z

This is actually working pretty well, but I think it could be done even better using a Chart object. The paintable canvas suffers from the issue of the plot coordinate 0,0 being in the upper left hand corner of the object, and it would be nicer to have 0,0 in the lower left hand corner. That being said, how would I take the dataset coming in from the tag and:

  1. skip the first 10 rows (which contain configuration data)
  2. take every odd row and place it into a new dataset column 1
  3. take every even row and place it into a new dataset column 2

Using the two columns of data I could then plot the points out on a regular chart object. I get the general concept of how to do this using python scripting, but am just not able to find some existing scripting for me to try and pull apart. Thanks for any help.

I don’t think the Chart will be able to do scatter plot like that.

Can you post a file with a typical string inside it? I’ll see what I can do with the paintable canvas to make it look more “charty”…

I likely won’t be able to do anything with it until the weekend though.

Data:

[3, 10, 1094, 0, 0, 2, 4, 0, 0, 0, 4, 880, 27, 906, 46, 919, 83, 914, 116, 895, 162, 871, 213, 843, 273, 850, 352, 883, 412, 934, 500, 996, 593, 1065, 666, 1125, 769, 1184, 871, 1242, 972, 1293, 1075, 1336, 1176, 1356, 1282, 1370, 1394, 1381, 1495, 1404, 1611, 1418, 1737, 1374, 1848, 1308, 1958, 1226, 2088, 1162, 2204, 1107, 2311, 1070, 2422, 1035, 2552, 1003, 2663, 997, 2769, 997, 2876, 1005, 2978, 1013, 3085, 1025, 3186, 1058, 3283, 1094, 3362, 1132, 3451, 1146, 3542, 1146, 3608, 1127, 3682, 1104, 3751, 1078, 3802, 1043, 3858, 1008, 3908, 975, 3955, 944, 4001, 917, 4020, 891, 4052, 867, 4061, 847, 4085, 845, 4094, 859, 4094, 883, 4094, 902, 4090, 918, 4061, 934, 4048, 935, 4015, 925, 3992, 921, 3964, 917, 3922, 911, 3872, 915, 3821, 922, 3769, 915, 3719, 900, 3658, 878, 3594, 847, 3519, 815, 3436, 781, 3366, 725, 3279, 657, 3200, 599, 3103, 554, 3029, 521, 2932, 490, 2830, 460, 2732, 428, 2626, 394, 2524, 359, 2417, 335, 2311, 335, 2200, 373, 2070, 434, 1954, 504, 1843, 560, 1718, 602, 1598, 628, 1482, 650, 1352, 670, 1241, 683, 1116, 695, 1001, 708, 889, 714, 782, 717, 680, 711, 583, 695, 505, 675, 407, 660, 329, 656, 269, 668, 209, 688, 162, 713, 106, 736, 60, 760, 37, 782, 4, 807, 0, 831, 0, 849, 4, 861, 9, 890, 32, 910, 50, 918, 97, 906, 129, 885, 171, 856, 240, 845, 304, 849, 374, 895, 453, 952, 531, 1018, 606, 1082, 703, 1144, 804, 1201, 901, 1255, 985, 1309, 1110, 1337, 1217, 1357, 1322, 1367, 1429, 1388, 1535, 1412, 1642, 1401, 1762, 1361, 1888, 1284, 1998, 1209, 2109, 1142, 2239, 1099, 2350, 1060, 2460, 1028, 2567, 1009, 2702, 999, 2803, 1006, 2910, 1010, 3016, 1018, 3117, 1038, 3220, 1067, 3307, 1103, 3391, 1133, 3483, 1147, 3557, 1136, 3636, 1117, 3701, 1092, 3780, 1064, 3835, 1032, 3885, 996, 3927, 964, 3960, 936, 4006, 911, 4024, 885, 4057, 864, 4075, 850, 4094, 852, 4094, 872, 4094, 891, 4094, 909, 4071, 927, 4057, 934, 4048, 931, 4015, 926, 3988, 919, 3941, 910, 3918, 910, 3867, 915, 3817, 917, 3761, 910, 3687, 893, 3631, 870, 3571, 844, 3497, 815, 3423, 779, 3336, 737, 3266, 668, 3183, 601, 3094, 543, 2997, 508, 2896, 480, 2794, 448, 2697, 416, 2609, 383, 2489, 346, 2382, 320, 2276, 336, 2169, 377, 2058, 435, 1919, 504, 1813, 566, 1684, 609, 1564, 639, 1448, 662, 1318, 679, 1207, 693, 1091, 704, 971, 714, 860, 721, 754, 721, 651, 714, 568, 698, 471, 674, 384, 658, 310, 657, 240, 668, 184, 687, 134, 713, 92, 736, 69, 760, 23, 788, 9, 812, 4, 832, 0, 853, 0, 874, 4, 896, 33, 913, 51, 913, 93, 904, 143, 876, 194, 851, 250, 832, 310, 864, 389, 910, 467, 971, 546, 1037, 635, 1105, 727, 1162, 810, 1218, 912, 1272, 1014, 1311, 1121, 1341, 1227, 1356, 1334, 1373, 1454, 1392, 1565, 1412, 1677, 1403, 1788, 1339, 1908, 1264, 2028, 1188, 2140, 1131, 2256, 1086, 2384, 1052, 2496, 1023, 2603, 1004, 2714, 1002, 2839, 1004, 2946, 1010, 3048, 1019, 3153, 1039, 3228, 1075, 3325, 1113, 3422, 1139, 3496, 1144, 3585, 1133, 3645, 1110, 3719, 1086, 3788, 1055, 3839, 1022, 3895, 989, 3941, 959, 3988, 931, 4015, 905, 4048, 882, 4057, 859, 4080, 847, 4094, 853, 4094, 873, 4094, 896, 4094, 914, 4071, 928, 4057, 938, 4043, 931, 4011, 922, 3982, 917, 3941, 913, 3890, 909, 3839, 917, 3788, 920, 3738, 908, 3677, 888, 3622, 865, 3557, 832, 3478, 800, 3395, 768, 3325, 702, 3238, 632, 3159, 577, 3062, 534, 2963, 503, 2862, 471, 2783, 439, 2682, 408, 2580, 373, 2473, 342, 2367, 331, 2251, 349, 2135, 398, 2020, 466, 1885, 533, 1774, 583, 1648, 619, 1524, 643, 1412, 665, 1297, 681, 1167, 693, 1056, 704, 945, 712, 815, 715, 722, 715, 635, 708, 537, 686, 435, 666, 370, 654, 287, 660, 227, 676, 171, 699, 120, 722, 79, 745, 46, 771, 14, 797, 4, 821, 0, 840, 4, 879, 23, 901, 46, 910, 83, 907, 124, 890, 157, 867, 203, 840, 259, 846, 342, 873, 407, 927, 490, 987, 573, 1055, 670, 1117, 750, 1177, 851, 1232, 953, 1280, 1050, 1319, 1157, 1343, 1262, 1358, 1369, 1374, 1475, 1401, 1605, 1413, 1711, 1386, 1822, 1324, 1948, 1246, 2068, 1175, 2179, 1120, 2295, 1080, 2423, 1045, 2530, 1020, 2636, 1006, 2747, 1004, 2854, 1008, 2960, 1009, 3063, 1019, 3164, 1044, 3261, 1082, 3363, 1118, 3441, 1140, 3525, 1142, 3594, 1129, 3677, 1105, 3738, 1079, 3793, 1046, 3848, 1012, 3900, 979, 3946, 952, 3992, 928, 4015, 903, 4052, 877, 4067, 855, 4090, 848, 4094, 858, 4094, 879, 4094, 896, 4094, 915, 4071, 934, 4057, 935, 4020, 929, 4001, 923, 3969, 915, 3932, 906, 3885, 912, 3835, 919, 3784, 915, 3728, 902, 3673, 882, 3594, 854, 3530, 822, 3456, 783, 3381, 730, 3294, 669, 3206, 611, 3127, 561, 3044, 522, 2956, 491, 2854, 463, 2752, 431, 2650, 398, 2549, 366, 2438, 333, 2332, 333, 2216, 370, 2091, 427, 1985, 491, 1873, 553, 1739, 596, 1628, 625, 1498, 649, 1378, 668, 1262, 681, 1133, 692, 1027, 703, 915, 711, 810, 713, 707, 708, 606, 694, 508, 677, 430, 658, 347, 655, 273, 664, 203, 683, 153, 707, 101, 735, 79, 757, 46, 780, 18, 805, 4, 828, 0, 848, 0, 865, 9, 887, 23, 901, 50, 906, 87, 901, 129, 884, 180, 857, 236, 842, 291, 849, 351, 887, 434, 941, 513, 1005, 591, 1073, 680, 1136, 777, 1191, 878, 1244, 981, 1290, 1087, 1321, 1194, 1343, 1295, 1360, 1401, 1383, 1512, 1402, 1619, 1416, 1729, 1375, 1859, 1302, 1971, 1226, 2082, 1159, 2211, 1107, 2322, 1069, 2433, 1038, 2553, 1016, 2673, 1006, 2780, 1005, 2886, 1003, 2989, 1006, 3094, 1019, 3196, 1052, 3289, 1091, 3367, 1131, 3464, 1150, 3539, 1148, 3623, 1129, 3683, 1105, 3757, 1076, 3826, 1041, 3877, 1004, 3923, 977, 3964, 949, 3997, 922, 4038, 895, 4052, 869, 4067, 848, 4090, 843, 4094, 856, 4094, 877, 4094, 899, 4080, 917, 4057, 931, 4052, 936, 4020, 929, 3997, 920, 3955, 914, 3923, 912, 3881, 915, 3826, 922, 3774, 917, 3710, 899, 3641, 876, 3585, 842, 3520, 797, 3437, 748, 3358, 695, 3289, 638, 3196, 587, 3109, 548, 3020, 520, 2919, 492, 2822, 457, 2720, 425, 2618, 391, 2512, 355, 2410, 340, 2303, 351, 2192, 394, 2072, 453, 1952, 521, 1836, 569, 1721, 602, 1591, 626, 1475, 646, 1345, 665, 1230, 680, 1114, 693, 990, 704, 883, 709, 777, 709, 675, 701, 573, 688, 490, 667, 403, 660, 333, 660, 254, 675, 194, 695, 143, 722, 97, 743, 73, 763, 32, 788, 9, 812, 4, 836, 0, 857]

Here is an example of trying to use the standard chart. It can display the whole dynagraph, so long as there is no intersection points. We have been investigating creating a new graph to display dynagraphs, through jfreechart, on a few of our projects. Its technically feasible, stay tuned.

EDIT: Attachments seem to have disappeared. Replaced.

Here’s one to mess around with.

This particular one will let you paste the sting into the text box. The script in the canvas will process the data, draw it, and populate the table.
Dynacard Graph_2018-03-22_1011.proj (39.7 KB)


Wow! You guys are awesome! Going to fool around with these for a while! Thanks!

Here is the screenshot of what my aforementioned window export looks like, using the standard chart. I am looking into getting around the intersection issue.

The window generates an error:

"Unable to open window “Card Viewer”

SerializationException: Unexpected parsing error during binary deserialization.
caused by IOExceptionWithCause: java.lang.ClassNotFoundException: com.inductiveautomation.factorypmi.application.components.TemplateRepeater
caused by ClassNotFoundException: com.inductiveautomation.factorypmi.application.components.TemplateRepeater

I take it I need the Template Repeater, but I thought it was already built into Ignition. Maybe I have the wrong version.

Sorry, here is one without that dependency.

Here is a new component that draws the overlaps properly. Included is an example window.

Let me know what you think.