Browse Source

Merge branch 'main' into development03

pull/421/head
lumapu 2 years ago
parent
commit
795cd64154
  1. 4
      README.md
  2. 2
      tools/rpi/README.md
  3. 8
      tools/rpi/ahoy.yml.example
  4. 102
      tools/rpi/hoymiles/__main__.py

4
README.md

@ -32,4 +32,6 @@ Please try to describe your issues as precise as possible and think about if thi
### Related Projects ### Related Projects
- [OpenDTU](https://github.com/tbnobody/OpenDTU) - [OpenDTU](https://github.com/tbnobody/OpenDTU)
- [DTU Simulator](https://github.com/Ziyatoe/DTUsimMI1x00-Hoymiles) <- Our sister project for Hoymiles HM-300, HM-600, HM-1200 (for ESP32 only!)
- [DTU Simulator](https://github.com/Ziyatoe/DTUsimMI1x00-Hoymiles)
<- Go here for Hoymiles MI-300, MI-600, MI-1200 Software

2
tools/rpi/README.md

@ -86,7 +86,7 @@ Required python modules
Some modules are not installed by default on a RaspberryPi, therefore add them manually: Some modules are not installed by default on a RaspberryPi, therefore add them manually:
``` ```
pip install crcmod pyyaml paho-mqtt pip install crcmod pyyaml paho-mqtt SunTimes
``` ```
Configuration Configuration

8
tools/rpi/ahoy.yml.example

@ -1,8 +1,12 @@
--- ---
ahoy: ahoy:
interval: 0 interval: 5
sunset: true sunset:
disabled: false
latitude: 51.799118
longitude: 10.615523
altitude: 1142
# List of available NRF24 transceivers # List of available NRF24 transceivers
nrf: nrf:

102
tools/rpi/hoymiles/__main__.py

@ -10,24 +10,16 @@ import struct
from enum import IntEnum from enum import IntEnum
import re import re
import time import time
import traceback
from datetime import datetime from datetime import datetime
from datetime import timedelta
from suntimes import SunTimes
import argparse import argparse
import yaml import yaml
from yaml.loader import SafeLoader from yaml.loader import SafeLoader
import paho.mqtt.client import paho.mqtt.client
import hoymiles import hoymiles
def main_loop(do_init):
"""Main loop"""
inverters = [
inverter for inverter in ahoy_config.get('inverters', [])
if not inverter.get('disabled', False)]
for inverter in inverters:
if hoymiles.HOYMILES_DEBUG_LOGGING:
print(f'Poll inverter {inverter["serial"]}')
poll_inverter(inverter, do_init)
class InfoCommands(IntEnum): class InfoCommands(IntEnum):
InverterDevInform_Simple = 0 # 0x00 InverterDevInform_Simple = 0 # 0x00
InverterDevInform_All = 1 # 0x01 InverterDevInform_All = 1 # 0x01
@ -48,6 +40,71 @@ class InfoCommands(IntEnum):
GetSelfCheckState = 30 # 0x1e GetSelfCheckState = 30 # 0x1e
InitDataState = 0xff InitDataState = 0xff
class SunsetHandler:
def __init__(self, sunset_config):
self.suntimes = None
if sunset_config and sunset_config.get('disabled', True) == False:
latitude = sunset_config.get('latitude')
longitude = sunset_config.get('longitude')
altitude = sunset_config.get('altitude')
self.suntimes = SunTimes(longitude=longitude, latitude=latitude, altitude=altitude)
self.nextSunset = self.suntimes.setutc(datetime.now())
print (f'Todays sunset is at {self.nextSunset}')
def checkWaitForSunrise(self):
if not self.suntimes:
return
# if the sunset already happened for today
now = datetime.now()
if self.nextSunset < now:
# wait until the sun rises tomorrow
tomorrow = now + timedelta(days=1)
nextSunrise = self.suntimes.riseutc(tomorrow)
self.nextSunset = self.suntimes.setutc(tomorrow)
time_to_sleep = (nextSunrise - datetime.now()).total_seconds()
print (f'Waiting for sunrise at {nextSunrise} ({time_to_sleep} seconds)')
if time_to_sleep > 0:
time.sleep(time_to_sleep)
print (f'Woke up... next sunset is at {self.nextSunset}')
return
def main_loop(ahoy_config):
"""Main loop"""
inverters = [
inverter for inverter in ahoy_config.get('inverters', [])
if not inverter.get('disabled', False)]
sunset = SunsetHandler(ahoy_config.get('sunset'))
loop_interval = ahoy_config.get('interval', 1)
try:
do_init = True
while True:
sunset.checkWaitForSunrise()
t_loop_start = time.time()
for inverter in inverters:
if hoymiles.HOYMILES_DEBUG_LOGGING:
print(f'Poll inverter {inverter["serial"]}')
poll_inverter(inverter, do_init)
do_init = False
print('', end='', flush=True)
if loop_interval > 0:
time_to_sleep = loop_interval - (time.time() - t_loop_start)
if time_to_sleep > 0:
time.sleep(time_to_sleep)
except KeyboardInterrupt:
sys.exit()
except Exception as e:
print ('Exception catched: %s' % e)
traceback.print_exc()
raise
def poll_inverter(inverter, do_init, retries=4): def poll_inverter(inverter, do_init, retries=4):
""" """
Send/Receive command_queue, initiate status poll on inverter Send/Receive command_queue, initiate status poll on inverter
@ -310,25 +367,4 @@ if __name__ == '__main__':
mqtt_client.subscribe(topic_item[1]) mqtt_client.subscribe(topic_item[1])
mqtt_command_topic_subs.append(topic_item) mqtt_command_topic_subs.append(topic_item)
loop_interval = ahoy_config.get('interval', 1) main_loop(ahoy_config)
try:
do_init = True
while True:
t_loop_start = time.time()
main_loop(do_init)
do_init = False
print('', end='', flush=True)
time_to_sleep = loop_interval - (time.time() - t_loop_start)
if loop_interval > 0 and time_to_sleep > 0:
time.sleep(time_to_sleep)
except KeyboardInterrupt:
sys.exit()
except Exception as e:
print ('Exception catched: %s' % e)
raise

Loading…
Cancel
Save