rest request result not json conform
-
Hallo,
my rest request works very well, but the resulting string is not json conform. Some parameters do not have " " around them. Please see attachment. This is true for all devices and also for rest/all
URL = http://10.0.0.50/rest/sensor/28B01DC107000045
Temp1 = b'{"interval": 15, "value": 19.0, "circuit": "28B01DC107000045", "address": "28B01DC107000045", "time": 1480241871.437477, "typ": "DS18B20", "lost": false, "dev": "temp"}'where can I change this in order to get a propper json result.
-
Hello,
see this: https://github.com/UniPiTechnology/evok/blob/master/evok/owclient.py#L107-L111
and also this for other devices: https://github.com/UniPiTechnology/evok/blob/master/evok/unipig.py#L396
-
Hi Tomas,
thanks for your sunday response!
I am not so familiar with python yet. I tried to change the statements but it did not work:def full(self): itv = '"%s"' % str(self.interval) return {'dev': 'temp', 'circuit': self.circuit, 'address': self.address, 'value': self.value, 'lost': self.lost, 'time': self.time, 'interval': itv, 'typ': self.type}
please have a look and suggest what I should do.
Thanks
Hannes -
The function called full is for every device - Input, AnalogInput, Relay,.. so you have to change it for each device.
For me this worked well for digital input
def full(self): return {'dev': 'input', 'circuit': self.circuit, 'value': self.value, 'time': str(self.tick), 'debounce': self.debounce, 'counter_mode': self.counter_mode == 'rising' or self.counter_mode == 'falling'}
-
Hi Tomas,
did not work :-(
I have put a debug print into def full(self). It was not printed -> the routine was not executedfyi my testprogramm :100:
#!/usr/bin/python import urllib.request import subprocess import time #---------------------------------------------------------- def restart_evok(): subprocess.call(['sudo', 'service', 'evok', 'stop']) time.sleep(1) print("EVOK stoped") subprocess.call(['sudo', 'service', 'evok', 'start']) time.sleep(1) print("EVOK started" + "\n") #---------------------------------------------------------- restart_evok() Relay = 1 url='http://10.0.0.50/rest/relay/'+str(Relay) print ('URL = ' + url) unipi = urllib.request.urlopen(url).read() print ('R1 = ' + str(unipi) + "\n") Temp1 = "28B01DC107000045" url='http://10.0.0.50/rest/sensor/' + Temp1 print ('URL = ' + url) unipi = urllib.request.urlopen(url).read() print ('Temp1 = ' + str(unipi) + "\n")
it looks like websocket is handled elsewhere in evok.
any idea? -
@juntiedt Are you sure you are editing the full method in right places? I just tried it for DS18B20 sensor and works well:
class DS18B20(MySensor): # thermometer def full(self): return {'dev': 'temp', 'circuit': self.circuit, 'address': self.address, 'value': self.value, 'lost': self.lost, 'time': str(self.time), 'interval': self.interval, 'typ': self.type}
And the output was as expected:
>>> print urllib.urlopen("http://192.168.1.107/rest/sensor/28A83B60070000FD").read() {"interval": 15, "value": 22.4, "circuit": "28A83B60070000FD", "address": "28A83B60070000FD", "time": "1480336515.68", "typ": "DS18B20", "lost": false, "dev": "temp"}
-
sorry, but is this the right place to edit on my Raspi?
/home/pi/evok/evok/owclient.py -
That is only a temporary folder where the source was downloaded. The application is located in /opt/evok/
-
Hallo Tomas,
Problem solved!
Thanks for your support.Hannes
-
Hallo Tomas,
the problem above is solved but now the unipi control panel does not work correctly with the above suggested changes.
The web application needs also to be changed to work with strings. But where to change?Hannes
-
@juntiedt The place to look at is here: https://github.com/UniPiTechnology/evok/blob/master/www/evok/js/wsbase.js#L11-L45
Located in /var/www/evok/
-
I am not familiar with java script.
Due to my changes in the python code msg.circuit and msg.value should be in string format which I have to reformat in java script to int or float .....?
Please have a look at my code below.
control panel only shows relay 1 and input 1function SyncDevice(msg) { //todo: add name as parameter var name = ""; var circuit = parseInt(msg.circuit); <----- var dev_type = msg.dev; var value = parseInt(msg.value); <------ var unit = ""; var ns = "unipi_" + dev_type + "_" + circuit; if (dev_type == 'ai') { name = "Analog input " + circuit; value = value.toFixed(3); <------ unit = "V"; } else if (dev_type == 'ao') { name = "Analog output " + circuit; unit = "V"; value = value.toFixed(1); <------ } else if (dev_type == 'relay') { name = "Relay " + circuit; } else if (dev_type == 'input') { name = "Input " + circuit; } else if (dev_type == 'temp') { name = "Sensor " + msg.typ + " - " + circuit; if value == null) { value = "null"; } else { value = value.toFixed(1); unit = "°C"; } }
-
You should parse the string according to the expected data type. Eg. if you make integer from float right at the beginning you wont be able to get a float from that later on. So it should be something like this:
function SyncDevice(msg) { //todo: add name as parameter var name = ""; var circuit = parseInt(msg.circuit); var dev_type = msg.dev; var value = msg.value; <------ var unit = ""; var ns = "unipi_" + dev_type + "_" + circuit; if (dev_type == 'ai') { name = "Analog input " + circuit; value = parseFloat(value).toFixed(3); <------ unit = "V"; } else if (dev_type == 'ao') { name = "Analog output " + circuit; unit = "V"; value = parseFloat(value).toFixed(1); <------ } else if (dev_type == 'relay') { name = "Relay " + circuit; value = parseInt(value); <------ } else if (dev_type == 'input') { name = "Input " + circuit; value = parseInt(value); <------ } else if (dev_type == 'temp') { name = "Sensor " + msg.typ + " - " + circuit; if (value == null || value == "") { value = "null"; } else { value = parseFloat(value).toFixed(1); <------ unit = "°C"; } }
-
super!
everything is ok now
great support
thank you -
Hi Tomas,
I still have a little problem with the control panel.
After my changes in wsbase.js my 1-wire sensor circuits are cut off at the first letter. See picture:I changed my code in wsbase as follows:
function SyncDevice(msg) { //todo: add name as parameter var name = ""; var circuit_a = msg.circuit; <------------------------ var circuit = parseInt(msg.circuit); var dev_type = msg.dev; var value = msg.value; var unit = ""; var ns = "unipi_" + dev_type + "_" + circuit; if (dev_type == 'ai') { name = "Analog input " + circuit; value = parseFloat(value).toFixed(3); unit = "V"; } else if (dev_type == 'ao') { name = "Analog output " + circuit; unit = "V"; value = parseFloat(value).toFixed(1); } else if (dev_type == 'relay') { name = "Relay " + circuit; value = parseInt(value); } else if (dev_type == 'input') { name = "Input " + circuit; value = parseInt(value); } else if (dev_type == 'temp') { name = "Sensor " + msg.typ + " - " + circuit_a; <------------------------ if (value == null || value == ""){ value = "null"; } else { value = parseFloat(value).toFixed(1); unit = "°C"; } }
unfortunately no success.
What have I done wrong? -
hi Tomas,
sorry for my recent post!
I have solved the problem!
I had to delete the cache of my chrom browser and now it works!have a nice Weekend