#python #json #python-3.x #node-red
#python #json #python-3.x #узел-красный
Вопрос:
Я пытаюсь запустить пустую функцию python3 (только return msg
в ней) в node-red с узлом ‘node-red-contrib-python3-function’, но я получаю ошибку, указанную в названии. У меня установлен Python 3.7.3 atm. Полученное сообщение об ошибке (повторяется 10 раз):
10 Apr 13:55:38 - [info] [python3-function:TEST] Python function 'TEST' running on PID 4616
10 Apr 13:55:40 - [info] [python3-function:TEST] Raw message received: b'x01x00x00x00x00x00x00x00?x00x00x00x00x00x00x00{"topic":"","payload":1554897340119,"_msgid":"c6460d66.0d218"}n'
10 Apr 13:55:40 - [error] [python3-function:TEST] Traceback (most recent call last):
File "<string>", line 72, in <module>
File "C:Python37libjson__init__.py", line 343, in loads
s = s.decode(detect_encoding(s), 'surrogatepass')
File "C:Python37libencodingsutf_32_le.py", line 11, in decode
return codecs.utf_32_le_decode(input, errors, True)
UnicodeDecodeError: 'utf-32-le' codec can't decode bytes in position 16-19: code point not in range(0x110000)
10 Apr 13:55:40 - [error] [python3-function:TEST] Python Function process exited with code 1
10 Apr 13:55:40 - [info] [python3-function:TEST] Python function 'TEST' running on PID 8640
10 Apr 13:55:42 - [info] [python3-function:TEST] Raw message received: b'x01x00x00x00x00x00x00x00@x00x00x00x00x00x00x00{"topic":"","payload":1554897342120,"_msgid":"d57b8b5f.5ef468"}n'
10 Apr 13:55:42 - [error] [python3-function:TEST] Traceback (most recent call last):
File "<string>", line 72, in <module>
File "C:Python37libjson__init__.py", line 343, in loads
s = s.decode(detect_encoding(s), 'surrogatepass')
File "C:Python37libencodingsutf_32_le.py", line 11, in decode
return codecs.utf_32_le_decode(input, errors, True)
UnicodeDecodeError: 'utf-32-le' codec can't decode bytes in position 16-19: code point not in range(0x110000)
10 Apr 13:55:42 - [error] [python3-function:TEST] Python Function process exited with code 1
Следующий код выполняется узлом (находится в python3-function.js в этой папке node modules lib) при развертывании потока я сам добавил печать необработанного сообщения.
def python_function(msg):
` indentLines(config.func, 4)
`
while True:
raw_msg = channel.readline()
print(f"Raw message received: {raw_msg}")
if not raw_msg:
raise RuntimeError('Received EOF!')
msg = json.loads(raw_msg)
msgid = msg["_msgid"]
node = Node(msgid, channel)
res_msgs = python_function(msg)
node.send(res_msgs)
`
Где канал:
channel = None
if sys.version_info[0]<3:
channel = os.fdopen(3, "r ")
else:
channel = os.fdopen(3, "rb", buffering=0)
Узел определяется как:
class Node(object):
def __init__(self, msgid, channel):
self.__msgid = msgid
self.__channel = channel
def send(self, msg):
msg = Msg(Msg.SEND, msg, self.__msgid)
self.send_to_node(msg)
def log(self, *args):
msg = Msg(Msg.LOG, args, self.__msgid)
self.send_to_node(msg)
def warn(self, *args):
msg = Msg(Msg.WARN, args, self.__msgid)
self.send_to_node(msg)
def error(self, *args):
msg = Msg(Msg.ERROR, args, self.__msgid)
self.send_to_node(msg)
def status(self, *args):
msg = Msg(Msg.STATUS, args, self.__msgid)
self.send_to_node(msg)
def send_to_node(self, msg):
m = msg.dumps()
if sys.version_info[0]>2:
m = m.encode("utf-8")
self.__channel.write(m)
Комментарии:
1. Ваша проблема здесь в том, что возвращаемый объект
channel.readline()
не является чистым JSON. Впереди есть пара байтов, которые нельзя преобразовать обратно в кодировку utf-32. Так что посмотрите, кто отправляет сообщение на канал2. Я не могу изменить все, что отправляется на этот канал. Я понятия не имею, как node-red работает таким образом. Я думаю, лучше всего было бы попытаться просто удалить байты перед ‘{‘, если это возможно.