Degree Symbol not supported in system.util.jsonDecode?

We have a jsonString which contains the degree symbol. When we try to decode that string it errors out, see example code and error below.

Should I be encoding the degree symbol differently? I’ve tried many different formats and can’t seem to make anything work.

Code:

deg = '°'
config = [{'degree': deg}]
print config

newConfig = system.util.jsonDecode(str(config))
print newConfig

Error results:

Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43) 
[OpenJDK 64-Bit Server VM (Azul Systems, Inc.)] on java11.0.6

>>> 
[{'degree': '\xc2\xb0'}]
Java Traceback:
Traceback (most recent call last):
  File "<input>", line 6, in <module>
	at org.json.JSONTokener.syntaxError(JSONTokener.java:430)

	at org.json.JSONTokener.nextString(JSONTokener.java:282)

	at org.json.JSONTokener.nextValue(JSONTokener.java:355)

	at org.json.JSONObject.<init>(JSONObject.java:201)

	at org.json.JSONTokener.nextValue(JSONTokener.java:358)

	at org.json.JSONArray.<init>(JSONArray.java:127)

	at org.json.JSONArray.<init>(JSONArray.java:160)

	at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.jsonDecode(SystemUtilities.java:427)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.base/java.lang.reflect.Method.invoke(Unknown Source)

org.json.JSONException: org.json.JSONException: Illegal escape. at 15 [character 16 line 1]


	at org.python.core.Py.JavaError(Py.java:552)

	at org.python.core.Py.JavaError(Py.java:543)

	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)

	at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:520)

	at org.python.core.PyObject.__call__(PyObject.java:480)

	at org.python.core.PyObject.__call__(PyObject.java:484)

	at org.python.pycode._pyx106.f$0(<input>:7)

	at org.python.pycode._pyx106.call_function(<input>)

	at org.python.core.PyTableCode.call(PyTableCode.java:171)

	at org.python.core.PyCode.call(PyCode.java:18)

	at org.python.core.Py.runCode(Py.java:1614)

	at org.python.core.Py.exec(Py.java:1658)

	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:276)

	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:131)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:605)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:593)

	at java.desktop/javax.swing.SwingWorker$1.call(Unknown Source)

	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

	at java.desktop/javax.swing.SwingWorker.run(Unknown Source)

	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

	at java.base/java.lang.Thread.run(Unknown Source)

Caused by: org.json.JSONException: Illegal escape. at 15 [character 16 line 1]

	at org.json.JSONTokener.syntaxError(JSONTokener.java:430)

	at org.json.JSONTokener.nextString(JSONTokener.java:282)

	at org.json.JSONTokener.nextValue(JSONTokener.java:355)

	at org.json.JSONObject.<init>(JSONObject.java:201)

	at org.json.JSONTokener.nextValue(JSONTokener.java:358)

	at org.json.JSONArray.<init>(JSONArray.java:127)

	at org.json.JSONArray.<init>(JSONArray.java:160)

	at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.jsonDecode(SystemUtilities.java:427)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.base/java.lang.reflect.Method.invoke(Unknown Source)

	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188)

	... 19 more

Traceback (most recent call last):
  File "<input>", line 6, in <module>
	at org.json.JSONTokener.syntaxError(JSONTokener.java:430)

	at org.json.JSONTokener.nextString(JSONTokener.java:282)

	at org.json.JSONTokener.nextValue(JSONTokener.java:355)

	at org.json.JSONObject.<init>(JSONObject.java:201)

	at org.json.JSONTokener.nextValue(JSONTokener.java:358)

	at org.json.JSONArray.<init>(JSONArray.java:127)

	at org.json.JSONArray.<init>(JSONArray.java:160)

	at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.jsonDecode(SystemUtilities.java:427)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.base/java.lang.reflect.Method.invoke(Unknown Source)

org.json.JSONException: org.json.JSONException: Illegal escape. at 15 [character 16 line 1]

By passing str(config) to jsonDecode you are passing it invalid JSON, because that evaluates to “[{‘degree’: u’\xb0’}]”.

Play with this script to better understand:

deg = u'°'
config = [{'degree': deg}]
print str(config)

json = system.util.jsonEncode(config)
print json

newConfig = system.util.jsonDecode(json)
print newConfig

Hey Kevin,

Thanks for your response. I guess this more accurately portrays the situation we are encountering:

Can you provide recommendation on how to convert that back to a simple degree symbol?

if you use the code kevin provided then your print will have the degree symbol

That is correct, but the jsonEncode turns it into a string. We need it in a json object.

The degree symbol also needs a unicode descriptor.

config = [{'degree': u'°'}]

A couple more examples for context.

This is ultimately what I’m trying to do:

If I use u’ descriptor:

Edit: updated image for unicode descriptor

Neither [{'degree': '°F'}] nor [{'degree': u'°F'}] are legal JSON.

Your first line should be config = u'[{"degree": "°F"}]' - you need to mark your entire JSON string as unicode so that the Jython interpreter doesn’t try to fold down to ASCII. Similarly, any string literal containing a non-ASCII character (such as line 9, with a comparison against "°F" - should be prefixed with u. That’s a Python 2 constraint, and has nothing to do with JSON, and doesn’t belong in your actual JSON.

Thank you, sir! This fixed my problem. Appreciate the help.