Limiter inverter with RS485 load setting

Solar hot water to me (at the moment) just seems conflicted and unfortunate, but it is what it is for the system and societary rational that exists at the moment, although I could contine for a few pages on this... every positive difference counts.
Our solar hot water is electrically heated, it was a £100 box that you sit on the existing immersion heater circuit, it uses a Triac and current clamp sensor to vary the power going to the heating element to match whatever excess solar electricity you are generating. I worked out with the current price per KWh of gas and the maximum amount of heat that could be stored in our tank (approx 3.5 kwh from luke warm) and the limited amount of excess power we generate the payback time was about 3 years. If I had used an electrician to install the device, picked a more expensive model or needed to alter the existing hot water system then the expense wouldn't have justified the savings.

Directly heated solar hot water (e.g. evacuated tube panels) don't really make financial sense for retrofit residential use, they are more efficent and you can fit a larger tank to act as a bigger energy store but the equipment and installation costs are too expensive to ever justify via cost savings. I think even if you were electrically heating your hot water (rather than gas boiler) you would struggle to break even over a sensible time frame. In fact it would probably be cheaper to fit more solar PV panels and divert the extra electricity to whichever house demand is most appropriate. Thereby consolidating on one energy transmission and storage medium rather than several (i.e. just electricity rather than heated hot water and natural gas via a boiler). Most of the UK Govt clean energy transition plan is about moving to a single source of energy transmission and then trying to green that, so get people off of natural gas boilers onto heat pumps, off of diesel into electric cars, then you can use multiple methods to clean up electricity generation and storage. Everything else like E10 petrol, Hydrogen in the gas network or lorries is really just a stopgap fix.

I'm currently debating on getting another 1-2 units vs the GTIL 2kW unit and driftying back towards another 1-2 units. I tend to switch off the units (via zero output - 2W) rather then keep them "online" and output active power, which I'm thinking (hope) should minimise the loading on the internal caps and extend life significantly. This is where I think many rather than the few could have an advantage for a multitude of reasons.

It's difficult to predict how something electronic will fail, it is not always governed by runtime hours or load and depends on the design. About the only thing that is certain is that if it is completely 'off' then it's not degrading as quickly, of course you have no way of knowing if on/off cycling is a contributor to longevity (e.g. CFL bulbs are sensitive to on/off cycling and short run times, but last ages if they are on for long periods of time. LED bulbs are limited by overall runtime hours - and heat). So probably best to just not worry about it!! One thing is certain, the more units you have operating in parallel the more likely you will experience a failure, but the less inconvinient it will be, and if 4 cheap units are the same price as 1 expensive unit then replacement costs would be lower, or at least spread out.

What I still don't about these units is the manufacturer or anyone representing them does not respond to "any" wetern consumer feedback (requests or otherwise). This is what I think really undermines any "real legitimacy" wihtin the market and greater confidence of consumers. I guess any manufuacturer can easily choose to destroy or miss out on part of their own market, although Homer Simpson would be a far better CEO in these instances. (maufcacturer : "do something !!!""). Western market is looking for a "solution", why not help ??? (FFS "leak" the full protocol !!!!!)
I would say this is the primary difference between buying a cheap device off of aliexpress and buying an expensive SMA or ABB inverter from a manufacturer approved local reseller. You are getting a better engineered device, but you are also getting installation support, spares and repairs service and a warranty. If you buy a soyosource inverter you are taking on these risks for the benefit of paying less and potentially having to buy twice... oh and the lack of regulatory approvals. Thats not to say its a bad design, it just lacks the value add of a local distributor and design (other brands are probably still made in China) .

For me personally if I had to buy a higher quality European developed inverter and ancillaries then the cost benefit case would be out the window and I wouldn't be using a storage battery for peak shaving and demand shifting. In return I have to take the risk it might not perform as well as a Tesla Powerwall, might give me more headaches consume more of my time and might just break at any moment... or it might work faultlessly for ever and ever.
 
Hi again All,

1. Is it possible to upgrade the software to the newer version?

2. Has anyone had the problem that their RS485 communication adaptor needs to be reset for the unit to operate again? It seems that the Soyo stops outputting at regular intervals and the only way to fix it is to kill the power supply to the adaptor and re-enable it again. It seems that I have one unit out of two that needs this to happen for. I've had to fit a relay that restarts the RS485 adaptor every 30 seconds. The battery levels are good. I am wondering if my bytecode is being sent to the wire correctly. I've attached a photo of the outages and my code:




Screenshot 2021-12-14 at 18.53.12.png

Python:
# VIRTUAL METER FOR SOYO SOURCE BRAND POWER INVERTERS
# V2.0 - targetting the main feed to zero
#
import bs4
import requests #pip install requests
import time
import datetime
import serial #pip install pyserial
import threading

## CREATE GLOBALS
byte0 = 36
byte1 = 86
byte2 = 0
byte3 = 33
byte4 = 0 ##(2 byte watts as short integer xaxb)
byte5 = 0 ##(2 byte watts as short integer xaxb)
byte6 = 128
byte7 = 8 ## checksum

serialWrite = serial.Serial('/dev/ttyAMA0', 4800, timeout=1) # define serial port on which to output RS485 data
currentOutput = 1
json_use = "http://192.168.86.248/feed/get.json?id=1&field=value&apikey=65631ea6b203f5dfdd36783f13e89e9e"
json_soc = "http://192.168.86.248/feed/get.json?id=9&field=value&apikey=65631ea6b203f5dfdd36783f13e89e9e"
def jsonSignal(url):
    r = requests.get(url)
    json_data = r.json()
    return json_data

def computeDemand(sourceValue):
    global currentOutput
    equilibrium = currentOutput+use
    if equilibrium >= 1000:
        equilibrium = 1000
    currentOutput = equilibrium
    print"currentOutput =", currentOutput
    return currentOutput
def createPacket(demand):
    byte4 = int(demand/256) ## (2 byte watts as short integer xaxb)
    if byte4 <= 0 or byte4 >= 256:
        byte4 = 0
    byte5 = int(demand)-(byte4 * 256) ## (2 byte watts as short integer xaxb)
    if byte5 <= 0 or byte5 >= 256:
        byte5 = 0
    byte7 = (264 - byte4 - byte5) #checksum calculation
    if byte7 >= 256:
        byte7 = 8
    return byte4, byte5, byte7

def writeToSerial(packet):
        bytes = [byte0,byte1,byte2,byte3,packet[0],packet[1],byte6,packet[2]]
        serialWrite.write(bytearray(bytes))
        #log.info("complete decimal packet: %s", bytes)
        #log.info("raw bytearray packet being sent to serial: %s", bytearray(bytes))
    #except ValueError:
        #log.error("Error writing to serial port, check port settings are correct in /dev/ ")
    #return packet

while True:
    soc = float(jsonSignal(json_soc))
    if soc >= 20:
        use = int(jsonSignal(json_use))
        print"soc =", soc
        print"use =", use
        demand = computeDemand(use)
        outputValue = demand/1
        print"demand =", demand
        simulatedPacket = createPacket(outputValue)
        writeToSerial(simulatedPacket)
        time.sleep(2)
    else:
        use = int(jsonSignal(json_use))
        print"soc =", soc
        print"use =", use
        demand = computeDemand(use)
        limpOutput = int(((soc*200)-2000)) #-0= from 30 to 20%, -2000= 20 to 10%
        if limpOutput >= demand:
            outputValue = demand/1
            print"demand (we are in limp mode)=", demand
            print"maximum output=",limpOutput
            simulatedPacket = createPacket(outputValue)
            writeToSerial(simulatedPacket)
            time.sleep(2)
        elif limpOutput < demand:
            outputValue = limpOutput/1
            print"demand (we are in limp mode)=", demand
            print"maximum output=",limpOutput
            simulatedPacket = createPacket(outputValue)
            writeToSerial(simulatedPacket)
            time.sleep(2)
 
The code appears fine, you are only sending a packet every 2 seconds, I use 1 second interval reliably and have driven it faster without problems. The inverter will stop outputting if it doesn't receive a packet regularly and resume as soon as it receives a packet, I think the timeout is around ?5? seconds so that shouldn't be your problem unless you are actually regularly sending corrupted packets and triggering the timeout. Sending a packet every half a second might fix that simply by virtue of sending 10 packets per 5 seconds rather than just 2, the inverter doesn't care if it gets more frequent or repeated data. The only thing you might notice is that it does internal averaging of the data it receives which will behave differently at a higher update rate, but that might even be a good thing.

Looking at the graph I presume the low points are the inverter cutting out... if so they do seem quite long breaks for the above described to be true, is it possible that the input signal you are using sometimes stops working or sends a value that results in the demand being set to zero or an error value?

What type of device are you running the python script on? It shouldn't really matter but there is a bit more complexity and chance for things to be misconfigured if it is a raspberry pi running via a USB to RS232 and then RS485 adapter alongside running other scripts, rather than say a ESP32 that only does the singular job of looping through a script and pinging its hardware serial port. If your python script is running on a single board computer that does other tasks the problem might not even be with your script, it could be other software interfering with the serial port, crashes and reboots of the computer, bad power supply etc. My experience of single board computers like the raspberry pi is they are very good for more complex tasks, but if you have something very simple that a micro-controller can do, then in general you will have a more robust and trouble free experience if you can implement it with the micro-controller. I am a recent convert to ESPHome which works very easily if you already use homeassistant and can get ESPHome installed without bother, bit of a learning curve to start with but then very quick and easy to implement even quite complex stuff.

Could it be that the RS485 converter or your RS232 serial port are faulty? Both are cheap enough that you could buy a second one for testing. Might also be worth testing the wiring, generally RS485 will work over anything but I did end up putting a resistor on one end of my cable as part of troubleshooting (turned out to be a loose screw terminal but I kept the resistor there as most best practice guides recommend having one to reduce ringing on the cable). I have a 3 meter cable run that I used a spare bit of CAT5 Ethernet cable for, one of the twisted pairs for the serial and some of the other wires for sending power and data to dallas temperature sensors.

One other thing I do is have the inverter connected via a WIFI controlled relay (actually its a wifi plug socket) to the mains electricity, that way when I am not using it I can turn it completely off, so my inverter gets power cycled twice a day. Might be worth investigating if turning it off and on makes the problem go away for a while. The inverter consumes 2-3 watts when idling at zero output with the screen backlight off so if its used intermittently on a battery it can be worthwhile setting up a way to completely power it off when not required... also gives me a really simple way to control it using home automation systems rather than via a demand signal script. A clockwork plug in timer would also work.

Hopefully something in the above sparks a solution.
 
So, another update... after about 3,400kWh and 3 years online one of the units appears to have a fault on voltage level detection, which has slowly evolved with a lower and lower reading of the AC line voltage. Very strange type of fault but it's now at a point where it says the AC line input is too low... Have not opened the unit up yet, but guessing it's one of the smaller capacitors that is failing. Rest of the display, fans, etc, all fine.
 
Since yesterday, my unit also start to act strange. I have had this unit running from solarpanels for about 2 years, then yesterday it started to write DC voltage too high and the unit rebooted. I disconnected the DC and it was still writing 27 volt in the display, about 20 seconds later it rebooted again still 27 volt, but falling - then it rebooted and voltage dropped to 26 volt another reboot and the cycle continued - I let it reboot / drop voltage until it was about 2 volt - now all disconnected I can still measure about 2 volt on the DC terminals... One time after a reboot it wrote 'Not connected M-board' - I opened the unit and checked all connections - all ok. Fuses are ok too. Yes another thing is that the AC voltage always stay on 239 volt, even when the limiter box is 226 volt...
IMG_0317.JPEG
 
yes my poor little soyo :-(

So I opened it again and checked the 'car' fuse like you said and it's ok, by looking inside - nothing burned or anything black. Now after a while with the unit disconnected, it's back to DC 0.00 V. When I connect my multimeter to the DC terminals I can measure ohm and it's rising (should be a good sign, capacitors is charging) after that there are some millivolts on the terminals. Next test was the self test, the first 3 lines is ok, then at 'testing relay on/off' it reboots. I don't know what that means...
 
I'm starting to think that it's the controller board, I find it odd that the AC voltage always shows 239 V (like this part of the software don't update) - when I do the self test, it's now different how far it gets before the reboot (one time it passed everything). When it reboots, it's like pulling the AC cord and plug it back in. I mean it just die, then boot up with the SoyoSource logo and back to the usual screen.
 
sorry, cant' help but here is a link for new controller
Soyo cpu
Hello BarianSuperGuy. I missed your previous few posts. Please make comments in English, please, as this is a world wide community and not everyone has the patience to run a translator to understand what the flow of topic discussion is. Plus it does make it a lot harder to search for things as the words aren't the same in different languages.
Thank you.
Korishan
 
Thank you for the link to the Soyo CPU - I think the link for the store is useful for the community, they have a lot of spareparts that I could not find. :)
 
Thank you very much for this great topic!
I got very much inspiration and know how from here.

I can not receive status frames from the soyo, the ones from the measurement box do come in...
I tried a lot of code, resistors, devices, even a 2nd soyo.... only b'' is read.
Any hints? A code snippet?

I'd be really happy to read soyos frames ;-)
 
Can you post a bit of your code?

Or use HTerm, look what happens and build your array.
 
Last edited:
One question ahead: Does soyo answer in any state? active / idle / battery / pv?
I hesitate to post one infunctional code snippet out of a mass... but i will.
Sending power requests to soyo works, with code from this thread.
Python:
#!/usr/bin/python3
# -*- coding: utf-8 -*-

from time import sleep
import serial
ser = serial.Serial('/dev/ttyUSB0',4800, timeout=10)

print(ser)

while True:
    print( ser.write( bytearray([0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) ) )
    ser.flush()
    ser.reset_input_buffer()
    try:
        raw = ser.read(15)
    except: pass
    
    print(raw)
    sleep(0.1)

results in:
Code:
./readsoyo.py

Serial<id=0x7fe7c31f67b8, open=True>(port='/dev/ttyUSB0', baudrate=4800, bytesize=8, parity='N', stopbits=1, timeout=10, xonxoff=False, rtscts=False, dsrdtr=False)
8
b''
8
b''
8
 
Last edited by a moderator:
Back
Top