Various tools, examples, and documentation for communicating with Hoymiles microinverters.
Ahoi is a project to bypass the original Hoymiles cloud solution.
In order to use this project, it is important what the area of application looks like.
With each version it is necessary to have an NRF24L01+.
In particular:
Click on the link below you are interested in.
There you will find further explanations on how to proceed. (*Note: It is still under construction!*)
* `doc/hoymiles-format-description.txt` is a [detailed description of the communications format](doc/hoymiles-format-description.md) and the history of this project
* `doc/getting-started-ESP8266.md` shows the [hardware setup for an ESP8266-based system](doc/getting-started-ESP8266.md)
* The `tools` folder contains various software tools for RaspberryPi, Arduino and ESP8266/ESP32:
* A [version for ESP8266](tools/esp8266/) that includes an web interface ![](../../actions/workflows/compile_esp8266.yml/badge.svg)
* A [version for Arduino Nano](tools/nano/NRF24_SendRcv/)
* An [alternative Version of the above](tools/NRF24_SendRcv/)
* A [different implementation](tools/HoyDtuSim/)
* An [implementation for Raspberry Pi](tools/rpi/) that polls an inverter and archives results as log files/stdout as well as posting them to an MQTT broker.
##### Most updated section
- [ESP8266](tools/esp8266/) that includes an web interface ![](../../actions/workflows/compile_esp8266.yml/badge.svg)
Contributors are always welcome!
##### will be updated as needed
- [Arduino Nano](tools/nano/NRF24_SendRcv/)
- [Raspberry Pi](tools/rpi/)
- [others](tools/nano/NRF24_SendRcv/)
If errors occur or you have suggestions for ideas, please feel free to contact us [here](https://github.com/grindylow/ahoy/issues).
This code is intended to run on a Wemos D1mini or similar. The code is based on 'Hubi's code, which can be found here: <https://www.mikrocontroller.net/topic/525778?page=3#7033371>
This page describes how the module of a Wemos D1 mini and ESP8266 is wired to the radio module, flashed and how the further steps are to communicate with the WR HM series.
The NRF24L01+ radio module is connected to the standard SPI pins. Additional there are 3 pins, which can be set individual: CS, CE and IRQ
These pins can be changed from the /setup URL
#### Compatiblity
For now the following inverters should work out of the box:
- HM350
- HM400
- HM600
- HM700
- HM800
- HM1200
- HM1500
The NRF24L01+ radio module is connected to the standard SPI pins.
Additional there are 3 pins, which can be set individual: CS, CE and IRQ
These pins can be changed in the http://<ip-adress>/setup URL or with a click on the Setup link.
- [ ] MQTT Discovery (HomeAssistant) im Setup optional machen
- [x] MQTT Subscribe nur beim Reconnect [Das subscribe in der Reconnect Procedure sollte doch nur nach einem conect ausgeführt werden und nicht bei jedem Duchlauf #139](https://github.com/grindylow/ahoy/issues/139)
DPRINTLN(DBG_INFO,F("Inverter ")+String(iv->id)+F(" has accepted power limit set point ")+String(iv->powerLimit[0])+F(" with PowerLimitControl ")+String(iv->powerLimit[1])+F(", written to dtu eeprom"));
}else{
DPRINTLN(DBG_INFO,F("Inverter ")+String(iv->id)+F(" has accepted power limit set point ")+String(iv->powerLimit[0])+F(" with PowerLimitControl ")+String(iv->powerLimit[1])+F(", written to dtu eeprom"));
}else
DPRINTLN(DBG_INFO,F("Inverter ")+String(iv->id)+F(" has accepted power limit set point ")+String(iv->powerLimit[0])+F(" with PowerLimitControl ")+String(iv->powerLimit[1]));
}
iv->devControlCmd=Init;
}
break;
default:
if(iv->devControlCmd==ActivePowerContr){
if(iv->devControlCmd==ActivePowerContr){
//case inverter did not accept the sent limit; set back to last stored limit
inv+=F("<label for=\"inv")+String(i)+F("ActivePowerLimitConType\">Active Power Limit Control Type</label>");
inv+=F("<select name=\"inv")+String(i);
// UGLY! But I do not know it a better way
// ToDo: Need Cookies, IndexDB or PWA for that or in general client browser storage
if(NULL!=iv){
if(iv->powerLimit[1]==AbsolutNonPersistent)
inv+=F("PowerLimitControl\"><option value=\"0\">absolute in Watt non persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1]==RelativNonPersistent)
inv+=F("PowerLimitControl\"><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1]==AbsolutPersistent)
inv+=F("PowerLimitControl\"><option value=\"256\">absolute in Watt persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1]==RelativPersistent)
inv+=F("PowerLimitControl\"><option value=\"257\">relativ in percent persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option></select>");
inv+=F("PowerLimitControl\"><option value=\"0\">absolute in Watt non persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");