Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't SET inverter, e.g. time1on #40

Closed
peterthevicar opened this issue Dec 29, 2023 · 15 comments
Closed

Can't SET inverter, e.g. time1on #40

peterthevicar opened this issue Dec 29, 2023 · 15 comments

Comments

@peterthevicar
Copy link

peterthevicar commented Dec 29, 2023

Hi, first of all thank you so much for all the work you've done on this; it's been a steep learning curve for me and so helpful.
I'm trying to write my own automation which is quite a bit simpler than yours as I don't have to worry about load shedding (being in the UK).

I have all the pieces except one: How to actually write settings back to the inverter! I changed the activeset for time1on to true and tried to use your flow but that didn't work for me.

Next I followed your node-red flow and used the same headers and payload. I even get a nice "Success" message back from SunSynk but the setting doesn't change. (See my python program below followed by its disappointing output)

Have you got this to work, and if so what is the secret?

Best wishes, Peter

def set_time1on(on_off):
    url = 'https://api.sunsynk.net/api/v1/common/setting/xxxxxxxx/set'
    #url = 'http://httpbin.org/post'
    payload = {'sn': "xxxxxxxx", 'time1on': on_off}
    headers = {'User-Agent': "Mozilla/5.0(Windows NT 10.0; Win64; x64; rv: 120.0) Gecko/20100101 Firefox/120.0",
           'Accept': "application/json",
           'Accept-Language': "en-US, en; q=0.5",
           'Accept-Encoding': "gzip, deflate, br",
           'Content-Type': "application/json;charset=UTF-8",
           'Authorization': "Bearer "+token,
           'Origin': "https://setting.inteless.com",
           'Connection': "keep-alive",
           'Referer': "https://setting.inteless.com/",
           'Sec-Fetch-Dest': "empty",
           'Sec-Fetch-Mode': "cors",
           'Sec-Fetch-Site': "same-site",
           'TE': "trailers"
           }
    r = requests.post(url, json=payload, headers=headers)
    print(r.json())

get_time1on() # get and print current state of time1on

set_time1on(False)

get_time1on()

time1on: True
{'code': 0, 'msg': 'Success', 'data': None, 'success': True}
time1on: True
@peterthevicar
Copy link
Author

Sorry, should have said I'm using your V2 files, and I completely accept it's a work in progress so absolutely no complaints!

@gdwaterworth
Copy link
Owner

Time?on is not working that is why it is still false in the active set. None of the true/false ones are for some reason. Let me know if you specifically get those working. Also note that sometimes it takes time for the change to happen and show

@peterthevicar
Copy link
Author

Thanks for taking the time to answer, I'll keep trying and let you know if I get anywhere.

@peterthevicar
Copy link
Author

Success! This seems to work. There are two significant differences from how I was trying before:

  1. I've used the entire settings list rather than just the one I want to change
  2. There is an extra header 'Content-Length' which is set to the length of the payload string

Also, as you suggested there is a delay at the SunSynk end before the change registers. For me it is between 4 and 10 seconds but presumably depends on server load.

The python below splits the enormously long payload into lhs and rhs with the time1on setting in the middle. It sets the new value for time1on and then splices it all back together again. Obviously the right way to do it is to query the settings beforehand but at least this is a proof-of-concept.

Hope this helps,

Best wishes, Peter

def set_time1on(on_off):
    url = 'https://api.sunsynk.net/api/v1/common/setting/xxxxxxxx/set'
    #url = 'http://httpbin.org/post'

    lhs = '{"sn":"xxxxxxxx","safetyType":"0","battMode":"-1","solarSell":"0","pvMaxLimit":"3600","energyMode":"1","peakAndVallery":"1","sysWorkMode":"2","sellTime1":"00:00","sellTime2":"01:30","sellTime3":"02:00","sellTime4":"02:30","sellTime5":"22:30","sellTime6":"23:00","sellTime1Pac":"5000","sellTime2Pac":"5000","sellTime3Pac":"5000","sellTime4Pac":"5000","sellTime5Pac":"5000","sellTime6Pac":"5000","cap1":"20","cap2":"100","cap3":"20","cap4":"20","cap5":"100","cap6":"20","sellTime1Volt":"58","sellTime2Volt":"58","sellTime3Volt":"49","sellTime4Volt":"49","sellTime5Volt":"49","sellTime6Volt":"49","zeroExportPower":"20","solarMaxSellPower":"6500","mondayOn":true,"tuesdayOn":true,"wednesdayOn":true,"thursdayOn":true,"fridayOn":true,"saturdayOn":true,"sundayOn":true,'
    rhs= ',"time2on":false,"time3on":false,"time4on":false,"time5on":true,"time6on":false,"genTime1on":false,"genTime2on":false,"genTime3on":false,"genTime4on":false,"genTime5on":false,"genTime6on":false}'
    payload = lhs + '"time1on":' + ('true' if on_off else 'false') + rhs # Python would have initial capital
    print(payload)

    headers = {'User-Agent': "Mozilla/5.0(Windows NT 10.0; Win64; x64; rv: 120.0) Gecko/20100101 Firefox/120.0",
           'Accept': "application/json",
           'Accept-Language': "en-GB,en;q=0.5",
           'Accept-Encoding': "gzip, deflate, br",
           'Content-Type': "application/json;charset=UTF-8",
           'Authorization': "Bearer "+token,
           'Content-Length': str(len(payload)),
           'Origin': "https://setting.inteless.com",
           'Connection': "keep-alive",
           'Referer': "https://setting.inteless.com/",
           'Sec-Fetch-Dest': "empty",
           'Sec-Fetch-Mode': "cors",
           'Sec-Fetch-Site': "cross-site",
           'TE': "trailers"
           }
    r = requests.post(url, data=payload, headers=headers)
    print(r.json())

@gdwaterworth
Copy link
Owner

gdwaterworth commented Dec 30, 2023 via email

@peterthevicar
Copy link
Author

OK I've narrowed it right down (code below works).
Summary:

  1. You DON'T need the Content-Length
  2. You DON'T need most of the other settings, not even the serial number
  3. You DO need time1on and genTime1on
def set_time1on(on_off):
    url = 'https://api.sunsynk.net/api/v1/common/setting/2212052408/set'
    #url = 'http://httpbin.org/post'
    lhs = '{'
    rhs= ',"genTime1on":false}'
    payload = lhs + '"time1on":' + ('true' if on_off else 'false') + rhs # Python would have initial capital
    print(payload)

    headers = {'User-Agent': "Mozilla/5.0(Windows NT 10.0; Win64; x64; rv: 120.0) Gecko/20100101 Firefox/120.0",
           'Accept': "application/json",
           'Accept-Language': "en-GB,en;q=0.5",
           'Accept-Encoding': "gzip, deflate, br",
           'Content-Type': "application/json;charset=UTF-8",
           'Authorization': "Bearer "+token,
           'Origin': "https://setting.inteless.com",
           'Connection': "keep-alive",
           'Referer': "https://setting.inteless.com/",
           'Sec-Fetch-Dest': "empty",
           'Sec-Fetch-Mode': "cors",
           'Sec-Fetch-Site': "cross-site",
           'TE': "trailers"
           }
    r = requests.post(url, data=payload, headers=headers)

@gdwaterworth
Copy link
Owner

gdwaterworth commented Dec 30, 2023 via email

@peterthevicar
Copy link
Author

Thanks, that's helpful. I have a very simple setup so not aware of the issues with bigger ones.

@peterthevicar
Copy link
Author

Around line 93 of the 'Create Inverter Update Request' node, I put in a kludge just to see if it works, which it does. I guess the next step is to do the pairing up of time?on with genTime?on via a mapping vector or a regexp substitution, and also read the current value to send back.

    } else if (BooleanEntities.includes(msg.payload.inverterid)) {
        if ((msg.payload.value === "on") || (msg.payload.value === "off")) 
        {
            if (msg.payload.value === "on") { outputmsg.payload[msg.payload.inverterid] = true;} else {outputmsg.payload[msg.payload.inverterid] = false ;}
            // PBCS: time1on change only accepted if genTime1on sent too
            if (msg.payload.inverterid == "time1on") {outputmsg.payload["genTime1on"] = false;}

@gdwaterworth
Copy link
Owner

I have a few idea's on how to do this. Will work on it

@gdwaterworth
Copy link
Owner

Code is in development branch for automation on gen and charge set automation

@peterthevicar
Copy link
Author

Would it be helpful if I test it here, or are you still refining things?

@gdwaterworth
Copy link
Owner

gdwaterworth commented Dec 31, 2023 via email

@gdwaterworth
Copy link
Owner

Code to support updates in all gen and charge set fields has been merged into the stable environment

@peterthevicar
Copy link
Author

peterthevicar commented Jan 2, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants