0

I'm an absolute beginner in get/post requests and micropython.

I'm programming my ESP8266 Wemos D1 mini as a HTTP server with micropython. My project consists of using a website to control the RGB values of a neopixel matrix hooked up to the D1 (all the code is on my GitHub here: https://github.com/julien123123/NeoLamp-Micro).

Basically, the website contains three sliders: one for Red, one for Green and one for Blue. A javascript code reads the value of each slider and sends it to the micropython code with using the POST method as follows :

getColors = function() {
  var rgb = new Array(slider1.value, slider2.value, slider3.value);
  return rgb;
};

postColors = function(rgb) {
  var xmlhttp = new XMLHttpRequest();
  var npxJSON = '{"R":' + rgb[0] + ', "G":' + rgb[1] + ', "B":' + rgb[2] + '}';
  xmlhttp.open('POST', 'http://' + window.location.hostname + '/npx', true);
  xmlhttp.setRequestHeader('Content-type', 'application/json');
  xmlhttp.send(npxJSON);
};

To recieve the resquest in micropython here's my code:

conn, addr = s.accept()
request = conn.recv(1024)
request = str(request)
print(request)

The response prints as follows:

b'POST /npx HTTP/1.1\r\nHost: 192.xxx.xxx.xxx\r\nConnection: keep-alive\r\nContent-Length: 27\r\nOrigin: http://192.168.0.110\r\nUser-Agent: Mozilla/5.0 (X11; CrOS x86_64 10323.46.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.107 Safari/537.36\r\nContent-type: application/json\r\nAccept: */*\r\nReferer: http://192.xxx.xxx.xxx/\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: fr,en;q=0.9,fr-CA;q=0.8\r\n\r\n{"R":114, "G":120, "B":236}'

The only important bit for me is at the end : {"R":114, "G":120, "B":236}. I want to use those values to change the color values of my neopixel object.

My question to you is how to I process the response so that I keep only the dictionary containing the RGB variables at the end of the response??

Thanks in advance (I'm almost there!)

hcheung
  • 3,377
  • 3
  • 11
  • 23

1 Answers1

1

This is more related to generic python data type. The data type of request is in bytes as indicated by prefix b in b'POST /npx HTTP/1.1...\r\n{"R":114, "G":120, "B":236}'. You will have to use decode() to convert it to string

import json

request = b'POST /npx HTTP/1.1\r\nHost: 192.xxx.xxx.xxx\r\nConnection: keep-alive\r\nContent-Length: 27\r\nOrigin: http://192.168.0.110\r\nUser-Agent: Mozilla/5.0 (X11; CrOS x86_64 10323.46.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.107 Safari/537.36\r\nContent-type: application/json\r\nAccept: */*\r\nReferer: http://192.xxx.xxx.xxx/\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: fr,en;q=0.9,fr-CA;q=0.8\r\n\r\n{"R":114, "G":120, "B":236}'
data = request.decode()    # convert to str
rgb = data.split('\r\n')[-1:]   #split the str and discard the http header
for color in rgb:
    print(color, type(color))
    d = json.loads(color)
    print(d, type(d))

The result of color is a str representation of an json object, the d will give you a python dict object to be used for further manipulation:

{"R":114, "G":120, "B":236} <class 'str'>
{'R': 114, 'G': 120, 'B': 236} <class 'dict'>
hcheung
  • 3,377
  • 3
  • 11
  • 23
  • Thank you very much. When I enter this exact code I get: `ValueError: syntax error in JSON`. if I remove json.loads() get exactly the the dictionary, but as a string. – Julien Treize Mar 09 '18 at 00:08
  • 1
    Okay. By the way, For your javascript, the correct way of creating a json to be sent should be `var npxJSON=JSON.stringify({R:rgb[0], G:rgb[1], B:rgb[2]);` – hcheung Mar 09 '18 at 00:24
  • Thank you for that, the ValueError stems from the result of `data.split('\r\n')[-1:]` which is `['{"R":114, "G":120, "B":236} ']` and JSON only accepts double quotations("). The only way around I found is to run the for loop once, with `json.loads( " [ " + color + " ] " )` and a second time returning just the color variable. There is most probably a more efficient way to do it, but I didn't find it yet. Could you edit the answer so that it reflects our discussion? then I could award you the answer – Julien Treize Mar 09 '18 at 21:10
  • I realised the result I shown was from `print(color)`, not from `print(json.loads(color))`, I updated my post and also explain why i use `json.loads(color)`. – hcheung Mar 10 '18 at 00:51