I am using a document memory tag to store some recipe information, and there is a “bug” right now with that tag type that requires you to cast the value to a string, and then jsonDecode it to use it as a dictionary.
i.e.
But somewhere along the way the keys in the dictionaries are made into unicode, instead of strings, so you have the u' appended to the beggining of each key.
i.e.
{u'example':1234, u'example2':[1,2,3,4,5]}
Is there an easy way to convert all of them to regular strings? I know I can do a .replace("u'", "'") on it while its a string, but that is not necessarily a very clean solution.
I want the output value 'tags' in JSON without the unicode characters! I can understand tag properties in unicode in order to facilitate localization in diifferent languages , but why are all keys also converted to unicode? Basically I am trying to generate a JSON array for a given list of tags of my choice from my DB, so that I can export the JSON to another Ignition DB for further processing. How can I do that?
The u’’ syntax is a printing/logging artifact. Strings in java are natively unicode, so that representation is the default conversion in jython. Note that getConfiguration isn’t returning JSON, it is returning a python list of python dictionaries. (Documented to do so, if you didn’t notice.) You would need to use jsonEncode or your own equivalent to yield JSON.
While converting dictionary to JSON using json.dumps(), some of the values in key/value pairs are enums such as Float4, the alarm properties etc which give error such as cannot be serialized! I guess we have to individually convert each key/value pair, there is no simple one function that will do the JSON conversion for this use case! Or is there any ? I don't know where to find jsonEncode documentation in scripting functions!
Thanks for the link. But I get an error 'RuntimeError: maximum recursion depth exceeded (Java StackOverflowError)' I think I have given a large dictionary object ! I will try some smaller object.
Actually this typically comes from giving the jsonEncode function a dictionary that includes a class instance of something that serializses in a non-json structure. For instance if one of your values is a BasicQualifiedValue then it will return this. I’m not exactly sure what your dictionary looks like prior to encoding, but you could potentially iterate through it and convert any BasicQualifiedValues to regular values
As given before, the dictionary is basically a tag properties dictionary generated by function system.tag.getConfiguration(basePath, recursive) in version 8. I think, things like Float4, Above setpoint, Below Setpoint etc are enums which are I think not parsable to JSON. It will be nice if I can get the properties of selected tags as JSON somehow, just like the system.tag.exportTags function in version 8, exports JSON for a given folder to a file. Sample JSON:
Try replacing the memory tag value at the end of the JSON before converting it, I am able to parse json with floats and what not in it.
In your case before the encode hardcode it with something like tags[0][‘value’] = 80 And see if that works.
As well the ‘path’ variable may be a BasicTagPath and not a string so you could try overwriting that as a string as well.
If those two solve it, it would be pretty easy to write a recursive script that goes through all of it to find oddly typed values like that and convert them
The problem is solved by simply casting these enums to string in python. It is producing the python dictionary which is parsable to JSON properly now! It was a simple problem!
If you look through the output printed by the third print statement, you will notice that there are alot of objectWrappers for each of the color properties:
The system.util.jsonEncode() function is not a fan of wrappers I have found, same happens when you pass a BasicQualifiedValue
Unfortunately these wrappers seem to be present on each of the objects within array properties. So to use them you will just need to cast them as dictionaries (and a list in the case of the tags)
Replace lines 8-11 with the following
personalAxes = [dict(axis) for axis in self.view.custom.axes]
personalColors = [dict(color) for color in self.view.custom.colors]
personalPens = [dict(pen) for pen in self.view.custom.pens]
personalTags = list(self.view.custom.tags)
Note:
I am not sure if this is considered a bug or not, because I can see almost no end user scenario where the preferred behavior would be to copy the wrapper and not a dictionary? However there may be some functional limitations here that I am unaware of causing this to be a necessity