JSON Bulk not working



  • Hi I am having trouble getting group_assignments in JSON Bulk write to work.

    I follow the API and my code is as follows:

    import requests
    
    url = "http://127.0.0.1:8081/bulk"
    
    payload = XXX
    headers = {'content-type': 'application/json'}
    response = requests.request("POST", url, data=payload, headers=headers)
    
    print(response.text)
    

    Now if I do payload as individual_assignments, the API seems to accept that:

    payload ="""{
    	"individual_assignments":
    		[
    			{
    				"device_type":"relay",
    				"device_circuit":"1",
    				"assigned_values":{"value":1}
    			},
    			{
    				"device_type":"relay",
    				"device_circuit":"2",
    				"assigned_values":{"value":0}
    			}
    		]
    	}"""
    

    I get

    {"status": "success", "data": {"individual_assignments": [1, 0]}}
    

    However, if I do "the same" as group_assignments:

    payload ="""{
    	"group_assignments":
    		[
    			{
    				"device_type":"relay",
    				"device_circuits":["1","2"],
    				"assigned_values":{"value":1}
    			}
    		]
    	}"""
    
    

    I keep getting

    {"status": "error", "message": "Internal Server Error", "code": 500}
    

    I also tried to have assigned_values as an array, to have device_type as array etc.ect.

    Can someone please provide me a working example on how to simultaneously set N relays?

    Thanks!

    BTW.
    Do you also experience problems when setting multiple values in a fast fashion (e.g. as above in individual_assignments, it happens that the relays are not assigned the provided values - only after I run the command multiple times. This is very unfortunate for time critical control applications... (e.g. I want two relays to switch at the same time and erraticaly one of them doe snot get switched).


  • administrators

    Hello @Gradient!

    It looks like you are right, the bulk on/off commands for UniPi 1.1 relays are broken. This is specific to these commands, as the issue is that all the relays are multiplexed via a single I2C controller chip and require feedback from the previous operation before the next one can be planned - which cannot happen when using the bulk commands as they currently are.

    I should be able to fix this shortly; the bulk API has been conceived long after UniPi 1.1 went into maintenance mode and was not thoroughly tested with it for that reason.

    My coworker has also forwarded to me your other email queries regarding JSONRPC, but unfortunately I have to say I was not able to replicate those - the relays appear to behave exactly as specified in that case. There is a delay between the individual RPC commands, but as each command is effectively a single HTTP request they will be necessarily serialised. They do however serialise correctly, which I've tested by switching all the relays every 50ms (and I'd like to note that the relays are not designed to switch at anything approaching these frequencies; they have an average lifetime of 10 000 state changes under load, 100 000 without)



  • This is weird. Can you confirm that the following python script works for you (please adjust IP):

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    import websocket
    import json
    url = "ws://192.168.0.105:8080/ws"
    ws = websocket.WebSocket()
    ws.connect(url)
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "1", "value":1})) #, "timeout":10}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "2", "value":1}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "3", "value":1}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "4", "value":1}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "5", "value":1})) #, "timeout":10}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "6", "value":1}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "7", "value":1}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "8", "value":1}))
        
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "1", "value":0})) #, "timeout":10}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "2", "value":0}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "3", "value":0}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "4", "value":0}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "5", "value":0})) #, "timeout":10}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "6", "value":0}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "7", "value":0}))
    ws.send(json.dumps({"cmd":"set", "dev":"relay", "circuit": "8", "value":0})) 
    
    ws.close()
    

    Because with my device this will not turn off all relays. It is erratic which relays are kept on and which aren't.
    If it does work with your UniPi 1.1, then my device is broken and I would like a replacement/fix.


  • administrators

    Hello @gradient,
    we can confirm, that the provided script doesn't turn off all relays, as it should. If a delay of at least 7.5ms is inserted between the commads, the result is as expected. We will look into this, but I cannot say when the fix will be released.

    Thank you for understanding,
    Martin