Page 1 of 1

Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Wednesday 22 February 2023 18:04
by mgerhard74
Hello,
i build a cheap Ahoy Dtu (13€) which is able to communicate with all Hoymiles HM-xxx PV microinverters.
Ahoy allows to interact with Mqtt and Rest Api standards. There is a documentation at the Ahoy Dtu project page online.

I made a LUA script to read the PV output power: (This is only a demo - feel free to add other data provided by the api)

Code: Select all

--Anlage des virtuellen Sensors Hoymiles: im Browser ausführen
--http://10.0.0.142:8080/json.htm?type=createvirtualsensor&idx=4&sensorname=HOYMILES&sensortype=248
JSON = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()    -- For Linux
   
commandArray = {}
    jsondata    = assert(io.popen('curl "http://10.0.0.156/api/live"'))
    device = jsondata:read('*all')
    jsondata:close()
    --data = JSON:decode(device).inverter[1].name
    --print('Devicename ' .. data)
    
    data = JSON:decode(device)
    --print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1].ch[1][3])
    
    if (data ~= nil) then
        commandArray[1] = {['UpdateDevice'] = 141 .. "|0|" ..tonumber(data.inverter[1].ch[1][3])}
    else
        commandArray[1] = {['UpdateDevice'] = 141 .. "|0|" .. 0 }
    end
return commandArray
hymiles_domo.png
hymiles_domo.png (32.63 KiB) Viewed 11743 times

A second project on i work is to build a PV storrage batterie with lifepo4 cells and a second Hoymiles microinverter. The Hoymiles microinverter can sent a power limit. So, if my house will consume 50 Watt at night, the Hoymiles gets a xml message to produce only 50 Watt from the 48V 5kWh batteries.
Batteries will be charged by a charger at day from PV.

This DzVents script is also a sample to set the power limit of inverter 0:

Code: Select all

return 
{
    on = 
    { 
        timer = { 'between 10 minutes before sunset and 10 minutes after sunrise' } 
    },
    
    execute = function(dz)
        
        local Amis = dz.variables('AMIS').value
        local HoymilesPower = dz.variables('HoymilesPower').value

        local Power = 0
        if Amis > 0 then
            Power = dz.utils.round (tonumber(HoymilesPower) + (tonumber(Amis) * 0.9),0)
        else
            Power = dz.utils.round (tonumber(HoymilesPower) - (tonumber(Amis) * -1.1),0)
        end
        dz.variables('HoymilesPower').set(tostring(Power))
        print ('Hoymiles Power set to: '..tostring(Power))
        dz.openURL(
        {
            url = 'http://10.0.0.156/api/ctrl',
            method = 'POST',
            headers = { ['Content-type'] = 'application/json' },
            postData = '{"id":0,"cmd":"limit_nonpersistent_absolute","val":' .. tostring(Power) ..'}',
        })
    end
}
Any ideas to run this script more than every minute? Maybe in LUA?
Amis is the Smartmeter value.

Gerhard

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Wednesday 15 March 2023 21:33
by belzig
infinite loop with

os.execute("sleep 15")

But im not sure, if it realy makes sense:

AHOY-DTU sends commands instantly to the inverter, but the inverter only accepts commands within 30 sec to 90 sec.
Every command is fire and forget.
If the smartmeter`s sampling rate is higher than 30 sec than this rate is the lower limit.

A lower inverval then 60 sec is probably completely useless

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Friday 31 March 2023 12:27
by belzig
I wrote a shell-script to read my fronius-inverter`s datalogger.
The script reads the power values and then sends the delta to my hm-300 to compensate the base load in the night.
hm-300 is connected to an 25,6 V battery.

prerequisites:
- Deep-Standy of Fronius-inverter has to be disabled ( Settings -> Fronius Solar WEB -> Logging during nighttime enabled)
- mqtt (mosquitto) has to be configured.
- HM-300 is not switched on or off by the script, you have to do this by
on:

Code: Select all

/usr/bin/mosquitto_pub  -t "inverter/ctrl/power/0" -m "1"
off:

Code: Select all

/usr/bin/mosquitto_pub  -t "inverter/ctrl/power/0" -m "0"

The script is an endless loop which can run stand-alone without domoticz, but it also can be integrated to domoticz-init script by
placing it as

Code: Select all

/home/pi/domoticz/script/smphm3.sh
and adding

Code: Select all

nohup /home/pi/domoticz/script/smphm3.sh > /var/log/smph3.log 2>&1
to

Code: Select all

 /etc/init.d/domoticz.sh
Domotics can start the loop in dzventscripts by

Code: Select all

os.execute("/usr/bin/touch /tmp/smphm3_unlock")
and pause the loop by.

Code: Select all

os.execute("/usr/bin/rm /tmp/smphm3_unlock")
Perhaps someone might find it usefull.

Code: Select all

#!/bin/bash
Limit=100
MLimit=0
LastRun=0
MaxPower=215
LastLimit=100
ldct=0
LimitAgg=0
Fronius_IP=1.2.3.4

DATUM=$(date +%d.%m.%y" "%H:%M:%S)
Lock=/tmp/smphm3_unlock 
/usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/0 -m $Limit
echo "$DATUM /usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/0 -m $Limit"

while true ; do
DATUM=$(date +%d.%m.%y" "%H:%M:%S)
	
 while [ -e $Lock ] ; do
DATUM=$(date +%d.%m.%y" "%H:%M:%S)


lSMpower=$(/usr/bin/curl -s --connect-timeout 1 "http://$Fronius_IP/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=0&DataCollection=CommonInverterData" |grep PowerReal_P_Sum |awk -F ":" '{ print $2 }'|awk -F "," '{ print $1 }' |awk -F "." '{ print $1 }')

lSMPower=$((lSMpower))

Limit=$(($LastLimit+$lSMpower-2))

	if [ $Limit -ge $MaxPower ]
	then
	 Limit=$MaxPower
	fi

	if [ $Limit -lt 10  ]
	then
		Limit=10
        fi	

limitdiff=$(($Limit-$LastLimit))
powerdiff=$(($lSMPower-$LastRun))

     LimitAgg=$(($LimitAgg+$Limit)) 
     ldct=$(($ldct+1))
     MLimit=$(($LimitAgg/$ldct))
    
  if [ $LastLimit -eq 215 -a $Limit -ne 215 ]
    then
	    Limit=$((($Limit+$MLimit+10)/2))
 fi	   


    echo "$DATUM P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct LAg:$LimitAgg ML:$MLimit"

if [ $limitdiff -ge 5 -o $limitdiff -le -5   ]
then

 if [   $powerdiff -ge 20 -o $powerdiff -le -10  ]
  then
	#echo "Powerdiff" $powerdiff
	
	       	echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/0 -m $Limit"
		/usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/0 -m $Limit
		
		LimitAgg=0
		ldct=0
	
  LastLimit=$((Limit))
  LastRun=$((lSMpower))

  else 
     echo "powerdiff low" $powerdiff
  fi

else
    echo "Limitdiff low" $limitdiff
fi
   
   
 if [ $ldct -ge 10 ]
    	then
	if [ $lSMPower -ge 20 -o $lSMPower -lt 0 ]
	   then

		Limit=$(($LimitAgg/$ldct))
		 echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/0 -m $Limit"
		/usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/0 -m $Limit
		LimitAgg=0
		ldct=0
		LastLimit=$Limit
	fi
 fi    
 sleep 10
 done
 echo "$DATUM smphm3 locked. Please set $Lock"
 sleep 120
done



Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Sunday 23 April 2023 12:12
by ld56
Hi! This was exactly was I had in mind for months :)
I've bought a HM-350 and I'm starting to play with it and a small battery which I will upgrade later.
I currently have a few problems with AhoyDTU and setting the power limit in the HM-350.

Is this kind of power limit works really well? Do you have a least 10w precision in the setting?
This power limit is great because I would not need a current limiter between the battery and the HM :)

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Tuesday 09 May 2023 13:44
by ld56
I've started to describe my full solar energy storage in this blog post, google this: DIY Solar battery storage and night injection (or check the link in profile)

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Saturday 20 May 2023 15:46
by SESTH
Thanks, that was exactly what I needed. I had to update the script for the current AhoyDTU © 2023, GIT SHA: 15ec6a0 :: 0.6.9.

Code: Select all

--Anlage des virtuellen Sensors Hoymiles: im Browser ausführen
--http://10.0.0.142:8080/json.htm?type=createvirtualsensor&idx=4&sensorname=HOYMILES&sensortype=248
JSON = assert(loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()    -- For Linux
   
commandArray = {}
    jsondata    = assert(io.popen('curl "http://mh-solar-01/api/record/live"'))
    device = jsondata:read('*all')
    jsondata:close()
    --data = JSON:decode(device).inverter[1].name
    --print('Devicename ' .. data)
    
    data = JSON:decode(device)
    --print(JSON:encode_pretty(data.inverter[1][15]))
    print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][15].val)
    
    if (data ~= nil) then
        commandArray[1] = {['UpdateDevice'] = 218 .. "|0|" ..tonumber(data.inverter[1][15].val)}
    else
        commandArray[1] = {['UpdateDevice'] = 218 .. "|0|" .. 0 }
    end
return commandArray

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Saturday 01 July 2023 10:04
by oeildefeu
Hello,
based on your script I updated them to fit my expectations :) thanks to you !
It follow the temperature of the onduler, the production and power.

Code: Select all

JSON = assert(loadfile "scripts/lua/JSON.lua")()
   
commandArray = {}
    local url_AhoyDTU = "http://192.168.0.70/api/record/live"
    local idx_temp = 827
    local idx_counter = 828
    local power = 0
    local Energy = 0
    local debug = false
    
    jsondata    = assert(io.popen('curl "'..url_AhoyDTU..'"'))
    device = jsondata:read('*all')
    jsondata:close()
    data = JSON:decode(device)
    if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][15].val) end
    power = tonumber(data.inverter[1][15].val)
    if debug then print ('Hoymiles Inverter 0 [Temp Celcius]: ' .. data.inverter[1][19].val) end
    temperature = tonumber(data.inverter[1][19].val)
    if debug then print ('Hoymiles Inverter 0 [Energy_total kWh]: ' .. data.inverter[1][22].val) end
    Energy = tonumber(data.inverter[1][22].val)*1000
    if (power ~= nil and Energy > 0) then
        commandArray[2] = {['UpdateDevice'] = idx_temp .. '|0|' .. temperature}
        commandArray[3] = {['UpdateDevice'] = idx_counter .. "|0|" .. power .. ";" .. Energy}
    else
        commandArray[1] = {['UpdateDevice'] = idx_counter .. "|0|" .. 0 }
    end
return commandArray

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Wednesday 12 July 2023 22:56
by belzig
New version of the script for 2 HM-300, with new syntax for AHOY-DTU 0.6.9

Code: Select all

#!/bin/bash
Limit=215
MLimit=0
LastRun=0
MaxPower=215
LastLimit=231
ldct=0
LimitAgg=0
Fronius_IP=1.2.3.4
INo=0
DATUM=$(date +%d.%m.%y" "%H:%M:%S)
Lock=/tmp/smphm3_unlock
RealMPow=231
/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/$INo -m $Limit"W"
echo "$DATUM /usr/bin/mosquitto_pub  -t inverter/ctrl/limit/$INo -m ${Limit}W"
sleep 5
INo=1
/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/$INo -m $Limit"W"
echo "$DATUM /usr/bin/mosquitto_pub  -t inverter/ctrl/limit/$INo -m ${Limit}W"
sleep 5

while true ; do
DATUM=$(date +%d.%m.%y" "%H:%M:%S)
 while [ -e $Lock ] ; do
 sleep 10
	 DATUM=$(date +%d.%m.%y" "%H:%M:%S)

#/usr/bin/curl -s --connect-timeout 1 "http://192.168.102.80/cm?cmnd=status%208" |awk -F"," '{ print $6}' |awk -F": " '{ print $2 }'

#cat  /tmp/smartmeter.out |grep PowerReal_P_Sum |awk -F ":" '{ print $2 }'|awk -F "," '{ print $1 }' |awk -F "." '{ print $1 }'

lSMpower=$(/usr/bin/curl -s --connect-timeout 1 "http://$Fronius_IP/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=0&DataCollection=CommonInverterData" |grep PowerReal_P_Sum |awk -F ":" '{ print $2 }'|awk -F "," '{ print $1 }' |awk -F "." '{ print $1 }')
#lSMpower=$(expr lSMpower)

#echo "Cons" $lSMpower
lSMPower=$((lSMpower))

Limit=$(((($LastLimit+$LastLimit+$lSMpower-4)/2)))
#Limit=$((($Limit+LastLimit)
	if [ $Limit -ge $MaxPower ]
	then
	 Limit=$MaxPower
	fi

	if [ $Limit -lt 10 ]
	then
		Limit=10
        fi	
if [ $LastLimit -eq $RealMPow ]
	then
  	   LastLimit=$MaxPower
fi  

limitdiff=$(($Limit-$LastLimit))
powerdiff=$(($lSMPower-$LastRun))

     LimitAgg=$(($LimitAgg+$Limit)) 
     ldct=$(($ldct+1))
     MLimit=$(($LimitAgg/$ldct))
    
  if [ $LastLimit -eq $MaxPower -a $Limit -ne $MaxPower ]
    then
	    Limit=$((($Limit+$MLimit+10)/2))
 fi	   


    echo "$DATUM P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct LAg:$LimitAgg ML:$MLimit"
#power=$(($power+1))
if [ $limitdiff -ge 5 -o $limitdiff -le -5   ]
then

 if [   $powerdiff -ge 20 -o $powerdiff -le -10  ]
  then
	#echo "Powerdiff" $powerdiff
	
		echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/0 -m $Limit W  "
		/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/0 -m $Limit"W"
                sleep 5	       	
		echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/1 -m $Limit W  "
		/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/1 -m $Limit"W"
		
		LimitAgg=0
		ldct=0
	
  #ldct=0
  LastLimit=$((Limit))
  LastRun=$((lSMpower))
  
	if [ $Limit -eq $MaxPower ]
	then
	 LastLimit=$RealMPow
	fi

  else 
     echo "powerdiff low" $powerdiff
  fi

else
    echo "Limitdiff low" $limitdiff
   ## ldct=$(($ldct+1))
fi
 # LastLimit=$((Limit))
 # LastRun=$((lSMpower))
#echo "P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct"
   
   
 if [ $ldct -ge 10 ]
    	then
	if [ $lSMPower -ge 20 -o $lSMPower -lt 0 ]
	   then

		Limit=$(($LimitAgg/$ldct))
		echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/0 -m $Limit W  "
		/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/0 -m $Limit"W"
		
		sleep 5
		echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/1 -m $Limit W  "
		/usr/bin/mosquitto_pub  -t inverter/ctrl/limit/1 -m $Limit"W"
		LimitAgg=0
		LimitAgg=0
		ldct=0
		LastLimit=$Limit
    	#LastLimit=300
	fi
 fi    

 done
 echo "$DATUM smphm3 locked. Please set $Lock"
 LastLimit=231
 sleep 90 
done

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Thursday 27 July 2023 7:35
by C4coer
hello everyone,
it's perfect for me.
thank you for the share

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Thursday 27 July 2023 9:10
by C4coer
hello everbody
I would like to retrieve the current production of each panel and the yield, i.e. indexes 3, 9 and 24, but how to integrate them into the script:
JSON = assert(loadfile "scripts/lua/JSON.lua")()

commandArray = {}
local url_AhoyDTU = "http://192.168.0.74/api/record/live"
local idx_temp = 310
local idx_counter = 312
local power = 0
local Energy = 0
local debug = false

jsondata = assert(io.popen('curl "'..url_AhoyDTU..'"'))
device = jsondata:read('*all')
jsondata:close()
data = JSON:decode(device)
if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][15].val) end
power = tonumber(data.inverter[1][15].val)
if debug then print ('Hoymiles Inverter 0 [Temp Celcius]: ' .. data.inverter[1][19].val) end
temperature = tonumber(data.inverter[1][19].val)
if debug then print ('Hoymiles Inverter 0 [Energy_total kWh]: ' .. data.inverter[1][22].val) end
Energy = tonumber(data.inverter[1][22].val)*1000
if (power ~= nil and Energy > 0) then
commandArray[2] = {['UpdateDevice'] = idx_temp .. '|0|' .. temperature}
commandArray[3] = {['UpdateDevice'] = idx_counter .. "|0|" .. power .. ";" .. Energy}
else
commandArray[1] = {['UpdateDevice'] = idx_counter .. "|0|" .. 0 }
end
return commandArray


-------------
I created for example an additional counter, but the values ​​are mixed:
local idx_counter1 = 313

and

if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][3].val) end
power = tonumber(data.inverter[1][3].val)

......
commandArray[1] = {['UpdateDevice'] = idx_counter .. "|0|" .. power .. ";" .. Energy}

thank you for your help

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Thursday 27 July 2023 10:51
by jvdz
What isn't working yet with the posted script?
Can you share an example Json data so we can test/debug your script?

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Thursday 27 July 2023 17:21
by C4coer
I think I found my mistake, what do you think?
if not for performance, I'll see.

------------------------------

JSON = assert(loadfile "scripts/lua/JSON.lua")()

commandArray = {}
local url_AhoyDTU = "http://192.168.0.74/api/record/live"
local idx_temp = 310
local idx_counter = 312
local idx_panel1 = 313
local idx_panel2 = 314
local power = 0
local Energy = 0
local debug = false

jsondata = assert(io.popen('curl "'..url_AhoyDTU..'"'))
device = jsondata:read('*all')
jsondata:close()
data = JSON:decode(device)

if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][15].val) end
power = tonumber(data.inverter[1][15].val)

if debug then print ('Hoymiles Inverter 0 [Temp Celcius]: ' .. data.inverter[1][19].val) end
temperature = tonumber(data.inverter[1][19].val)

if debug then print ('Hoymiles Inverter 0 [Energy_total kWh]: ' .. data.inverter[1][22].val) end
Energy = tonumber(data.inverter[1][22].val) * 1000

if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][3].val) end
power1 = tonumber(data.inverter[1][3].val)

if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][9].val) end
power2 = tonumber(data.inverter[1][9].val)


if (power ~= nil and Energy > 0) then
commandArray[2] = {['UpdateDevice'] = idx_temp .. '|0|' .. temperature}
commandArray[3] = {['UpdateDevice'] = idx_counter .. "|0|" .. power .. ";" .. Energy}
commandArray[4] = {['UpdateDevice'] = idx_panel1 .. "|0|" .. power1 .. ";" .. Energy}
commandArray[5] = {['UpdateDevice'] = idx_panel2 .. '|0|' .. power2 .. ";" .. Energy}
else
commandArray[1] = {['UpdateDevice'] = idx_counter .. "|0|" .. 0}



end

return commandArray

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Thursday 27 July 2023 18:00
by C4coer
included the performance of the micro inverter

JSON = assert(loadfile "scripts/lua/JSON.lua")()

commandArray = {}
local url_AhoyDTU = "http://192.168.0.74/api/record/live"
local idx_temp = 310
local idx_counter = 312
local idx_panel1 = 313
local idx_panel2 = 314
local idx_rendement = 315
local power = 0
local Energy = 0
local debug = false

jsondata = assert(io.popen('curl "'..url_AhoyDTU..'"'))
device = jsondata:read('*all')
jsondata:close()
data = JSON:decode(device)

if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][15].val) end
power = tonumber(data.inverter[1][15].val)

if debug then print ('Hoymiles Inverter 0 [Temp Celcius]: ' .. data.inverter[1][19].val) end
temperature = tonumber(data.inverter[1][19].val)

if debug then print ('Hoymiles Inverter 0 [Energy_total kWh]: ' .. data.inverter[1][22].val) end
Energy = tonumber(data.inverter[1][22].val) * 1000

if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][3].val) end
power1 = tonumber(data.inverter[1][3].val)

if debug then print ('Hoymiles Inverter 0 [Watt]: ' .. data.inverter[1][9].val) end
power2 = tonumber(data.inverter[1][9].val)

if debug then print ('Hoymiles Inverter 0 [%]: ' .. data.inverter[1][24].val) end
rend = tonumber(data.inverter[1][24].val)



if (power ~= nil and Energy > 0) then
commandArray[2] = {['UpdateDevice'] = idx_temp .. '|0|' .. temperature}
commandArray[3] = {['UpdateDevice'] = idx_counter .. "|0|" .. power .. ";" .. Energy}
commandArray[4] = {['UpdateDevice'] = idx_panel1 .. "|0|" .. power1 .. ";" .. Energy}
commandArray[5] = {['UpdateDevice'] = idx_panel2 .. '|0|' .. power2 .. ";" .. Energy}
commandArray[6] = {['UpdateDevice'] = idx_rendement .. '|0|' .. rend}
else
commandArray[1] = {['UpdateDevice'] = idx_counter .. "|0|" .. 0}



end

return commandArray

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Wednesday 18 October 2023 12:24
by psubiaco
Very nice info about Hoymiles inverter and integration in Domoticz. Thanks.
About scripting, I'm familiar only with LUA, where you can trigger a script by device change.
The idea is to change hoymiles immission limit as soon as the grid power meter is read.
Many examples available at https://github.com/CreasolTech/domoticz_lua_scripts (check file named script_device_*.lua)

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Tuesday 19 March 2024 17:16
by C4coer
Hello, I hadn't seen your question, can you be more clear?

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Tuesday 19 March 2024 17:17
by C4coer
psubiaco wrote: Wednesday 18 October 2023 12:24 Very nice info about Hoymiles inverter and integration in Domoticz. Thanks.
About scripting, I'm familiar only with LUA, where you can trigger a script by device change.
The idea is to change hoymiles immission limit as soon as the grid power meter is read.
Many examples available at https://github.com/CreasolTech/domoticz_lua_scripts (check file named script_device_*.lua)
Hello, I hadn't seen your question, can you be more clear?

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Wednesday 18 December 2024 13:34
by belzig
If you want to integrate Ahoy-DTU version 8.1.40 you have to change the script as follows
--------------------------------------------------

Code: Select all

  jsondata    = assert(io.popen('curl --connect-timeout 5 "http://YOUR_DTU_IP/api/inverter/id/0"'))
    device = jsondata:read('*all')
    jsondata:close()
    --data = JSON:decode(device).inverter[1].name
    --print('Devicename ' .. data)

    data = JSON:decode(device)
    --print(JSON:encode_pretty(data.inverter[1][15]))
-- print ('Hoymiles Inverter 1 [Voltage]: ' .. data.ch[2][1])
--  print ('Hoymiles Inverter 1 [Current]: ' .. data.ch[2][2])
--  print ('Hoymiles Inverter 1 [Power:] ' .. data.ch[2][3])

---------change 11 12 13 to your device Idx)
    if (data ~= nil) then
     commandArray[1] = {['UpdateDevice'] = 11  .. "|0|" ..tonumber(data.ch[2][1])}
     commandArray[2] = {['UpdateDevice'] = 12 .. "|0|" ..tonumber(data.ch[2][2])}
     commandArray[3] = {['UpdateDevice'] = 13  .. "|0|" ..tonumber(data.ch[2][3])}
     
--------------------------

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Wednesday 18 December 2024 14:39
by waltervl
It seems that Ahoy-DTU supports HA MQTT discovery protocol so an easy integration with Domoticz MQTT Auto Discover should be possible.
for example an issue regarding this: https://github.com/lumapu/ahoy/issues/1613
I could not really find proper Ahoy documentation on this.

Domoticz Wiki on MQTT Autodiscover https://wiki.domoticz.com/MQTT#Add_hard ... Gateway%22

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Tuesday 14 January 2025 17:18
by belzig
At the moment the Ahoy-DTU version 8.140 has stability problems when you use mqtt. So Gerhards script is still very useful.

I also rewrote my shell-skript for the zero-export in the way that it doesn´t need mqtt anymore.
Now it communicates via rest-api.

Here is the version for single Inverter and Fronius Symo GEN24 (you have to enable API Access (Communication->Solar-API)

The mqtt-calls are disabled by #

Code: Select all

#!/bin/bash
Limit=100
MLimit=0
LastRun=0
MaxPower=215
LastLimit=100
ldct=0
LimitAgg=0
Fronius_IP=1.2.3.5
INo=0
Cred=" -u mqttuser -P PASSWORD"
DATUM=$(date +%d.%m.%y" "%H:%M:%S)
Lock=/tmp/smphm3_unlock
DTUIP=1.2.3.4
#/usr/bin/mosquitto_pub $Cred -t inverter/ctrl/limit/$INo -m "${Limit}W"
CURLP="curl -X POST http://'$DTUIP'/api/ctrl" 

$CURLP   -H "Content-Type: application/json" -d '{"id":'$INo',"cmd": "limit_nonpersistent_absolute", "val":'$Limit'}'
#echo "$DATUM /usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/$INo -m $Limit"

while true ; do
DATUM=$(date +%d.%m.%y" "%H:%M:%S)
 sleep 30
 while [ -e $Lock ] ; do
 sleep 10
         DATUM=$(date +%d.%m.%y" "%H:%M:%S)

lSMpower=$(/usr/bin/curl -s --connect-timeout 1 "http://$Fronius_IP/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=0&DataCollection=CommonInverterData" |grep PowerReal_P_Sum |awk -F ":" '{ print $2 }'|awk -F "," '{ print $1 }' |awk -F "." '{ print $1 }')
#lSMpower=$(expr lSMpower)

#echo "Cons" $lSMpower
lSMPower=$((lSMpower))

Limit=$((($LastLimit+$lSMpower-2)))
#Limit=$((($Limit+LastLimit)
        if [ $Limit -ge $MaxPower ]
        then
         Limit=$MaxPower
        fi

        if [ $Limit -lt 10  ]
        then
                Limit=10
        fi

limitdiff=$(($Limit-$LastLimit))
powerdiff=$(($lSMPower-$LastRun))

     LimitAgg=$(($LimitAgg+$Limit))
     ldct=$(($ldct+1))
     MLimit=$(($LimitAgg/$ldct))

  if [ $LastLimit -eq $MaxPower -a $Limit -ne $MaxPower ]
    then
            Limit=$((($Limit+$MLimit+10)/2))
 fi


#    echo "$DATUM P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct LAg:$LimitAgg ML:$MLimit"
#power=$(($power+1))
if [ $limitdiff -ge 5 -o $limitdiff -le -5   ]
then

 if [   $powerdiff -ge 20 -o $powerdiff -le -10  ]
  then
        #echo "Powerdiff" $powerdiff
    echo "$DATUM P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct LAg:$LimitAgg ML:$MLimit"

           #            echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/$INo -m $Limit"
        #       /usr/bin/mosquitto_pub $Cred -t inverter/ctrl/limit/$INo -m "${Limit}W"
#               echo "/usr/bin/mosquitto_pub $Cred -t inverter/ctrl/limit/$INo -m ${Limit}W"
            $CURLP   -H "Content-Type: application/json" -d '{"id":'$INo',"cmd": "limit_nonpersistent_absolute", "val":'$Limit'}'

                LimitAgg=0
                ldct=0

  #ldct=0
  LastLimit=$((Limit))
  LastRun=$((lSMpower))

  else
  Dummy=1
#  echo "powerdiff low" $powerdiff
  fi

else
   Dummy=2
   # echo "Limitdiff low" $limitdiff
   ## ldct=$(($ldct+1))
fi
 # LastLimit=$((Limit))
 # LastRun=$((lSMpower))
#echo "P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct"


 if [ $ldct -ge 10 ]
        then
        if [ $lSMPower -ge 20 -o $lSMPower -lt 0 ]
           then

                Limit=$(($LimitAgg/$ldct))
#                echo "/usr/bin/mosquitto_pub  -t inverter/ctrl/limit_nonpersistent_absolute/$INo -m $Limit"
#               /usr/bin/mosquitto_pub $Cred -t inverter/ctrl/limit/$INo -m "${Limit}W"
        $CURLP   -H "Content-Type: application/json" -d '{"id":'$INo',"cmd": "limit_nonpersistent_absolute", "val":'$Limit'}'



                LimitAgg=0
                ldct=0
                LastLimit=$Limit
        #LastLimit=300
        fi
 fi

 done
 echo "$DATUM smphm3 locked. Please set $Lock"
 sleep 90
done

Re: Ahoy Dtu and Hoymiles HM-xxx integration

Posted: Wednesday 02 July 2025 14:40
by belzig
A version for Volkszähler (Hitchi Tasmota) for Orbis Energy-Meters e.g. EFR
in Tasmota this script was applied, to configure the output.

Code: Select all

>D
>B
->sensor53 r
>M 1
+1,3,s,16,9600,ENERGY
1,77070100010800ff@1000,Consumption,kWh,Total,4
; für Einspeisung (SGM-C8-xxx2xx)
;1,77070100020800ff@1000,Supply,kWh,Supply,4
; für Doppeltarifzähler (SGM-C8-xxxxTx)
;1,77070100010801ff@1000,Consumption_t1,kWh,Total_t1,4
;1,77070100010802ff@1000,Consumption_t2,kWh,Total_t2,4
;1,77070100020801ff@1000,Supply_t1,kWh,Supply_t1,4
;1,77070100020802ff@1000,Supply_t2,kWh,Supply_t2,4
1,77070100100700ff@1,Actual Power,W,Power,0
1,77070100200700ff@1,Voltage L1,V,Voltage,1
1,770701001f0700ff@1,Current L1,A,Current,2
1,770701000e0700ff@1,Frequency,Hz,Freq,1
1,77070100020800ff@1000,FeedIn,kWh,FeedIn,4
#


And here is the shell-script for VZ

Code: Select all

#!/bin/bash
Limit=100
MLimit=0
LastRun=0
MaxPower=215
LastLimit=100
ldct=0
LimitAgg=0
VZ_IP=192.168.0.1 # your Volkszaehler_IP
INo=1

DTUIP=192.168.0.2 # your DTU IP
DATUM=$(date +%d.%m.%y" "%H:%M:%S)
Lock=/tmp/smphm350_unlock
lSMPower=0

CURLP="curl --connect-timeout 1 -X POST http://$DTUIP/api/ctrl" # -H 'Content-Type: application/json'"
$CURLP   -H "Content-Type: application/json" -d '{"id":'$INo',"cmd": "limit_nonpersistent_absolute", "va
l":'$Limit'}'

while true ; do
DATUM=$(date +%d.%m.%y" "%H:%M:%S)
 sleep 30
 while [ -e $Lock ] ; do
 sleep 10
         DATUM=$(date +%d.%m.%y" "%H:%M:%S)

raw_data=$(curl -s --connect-timeout 1 "http://$VZ_IP/cm?cmnd=Status%208")

# Debug: Rohdaten ausgeben (optional)
#echo "Rohdaten: $raw_data" >&2

# Power-Wert extrahieren und bereinigen
lSMpower=$(echo "$raw_data" | awk -F '"Power":' '{print $2}' | awk -F "," '{print $1}')
lSMpower_cleaned=$(echo "$lSMpower" | tr -d '\r"'| tr -d '" ' | sed 's/[^0-9-]//g')

# Arithmetische Prüfung
if [[ "$lSMpower_cleaned" =~ ^-?[0-9]+$ ]]; then
    lSMPower=$((lSMpower_cleaned))
#    echo "Erfolg: Power-Wert ist $lSMPower"
else
    echo "Fehler: '$lSMpower' (bereinigt: '$lSMpower_cleaned') ist keine Zahl! Setze Default 5." >&2
    lSMPower=5
fi
lSMPower=$((lSMpower)) || lSMPower=5

Limit=$((($LastLimit+$lSMpower-2)))

        if [ $Limit -ge $MaxPower ]
        then
         Limit=$MaxPower
        fi

        if [ $Limit -lt 10  ]
        then
                Limit=10
        fi

limitdiff=$(($Limit-$LastLimit))
powerdiff=$(($lSMPower-$LastRun))

     LimitAgg=$(($LimitAgg+$Limit))
     ldct=$(($ldct+1))
     MLimit=$(($LimitAgg/$ldct))

  if [ $LastLimit -eq $MaxPower -a $Limit -ne $MaxPower ]
    then
            Limit=$((($Limit+$MLimit+10)/2))
 fi

if [ $limitdiff -ge 5 -o $limitdiff -le -5   ]
then

 if [   $powerdiff -ge 20 -o $powerdiff -le -10  ]
  then
        #echo "Powerdiff" $powerdiff
    echo "$DATUM P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct LAg:$LimitAgg ML:$MLimit"

              $CURLP   -H "Content-Type: application/json" -d '{"id":'$INo',"cmd": "limit_nonpersistent_absolute", "val":'$Limit'}'

                LimitAgg=0
                ldct=0

  #ldct=0
  LastLimit=$((Limit))
  LastRun=$((lSMpower))

  else
  Dummy=1
#  echo "powerdiff low" $powerdiff
  fi

else
   Dummy=2
   # echo "Limitdiff low" $limitdiff
   ## ldct=$(($ldct+1))
fi
 # LastLimit=$((Limit))
 # LastRun=$((lSMpower))
echo "P:$lSMPower L:$Limit LD:$limitdiff PD:$powerdiff LDct:$ldct"


 if [ $ldct -ge 10 ]
        then
        if [ $lSMPower -ge 20 -o $lSMPower -lt 0 ]
           then

                Limit=$(($LimitAgg/$ldct))
        $CURLP   -H "Content-Type: application/json" -d '{"id":'$INo',"cmd": "limit_nonpersistent_absolute", "val":'$Limit'}'
                LimitAgg=0
                ldct=0
                LastLimit=$Limit
        #LastLimit=300
        fi
 fi

 done
 echo "$DATUM smphm3 locked. Please set $Lock"
 sleep 90
done