diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 2c0da9b..67706c9 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -2,17 +2,33 @@ name: Docker Image CI on: push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' jobs: - - build: - - runs-on: python:3-slim - + docker: + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Build the Docker image - run: docker build . --file Dockerfile --tag sungather:$(date +%s) + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - run: echo "::set-output name=tag::v$(python setup.py --version)" + id: version + - uses: docker/setup-qemu-action@v1 + - uses: docker/setup-buildx-action@v1 + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/sungather:${{ steps.version.outputs.tag }},${{ secrets.DOCKERHUB_USERNAME }}/sungather:latest + - uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.REPO_TOKEN }}" + prerelease: false diff --git a/.gitignore b/.gitignore index b77924e..cd33ed3 100644 --- a/.gitignore +++ b/.gitignore @@ -115,3 +115,7 @@ dmypy.json # Pyre type checker .pyre/ + +# Intellij IDEA +.idea +*.iml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index d7de0b2..ba9408e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ FROM python:3-slim +RUN apt-get update && apt-get install -y build-essential python3-dev && rm -rf /var/lib/apt/lists/* + RUN useradd sungather WORKDIR /usr/src/sungather diff --git a/README.md b/README.md index a2b6245..d91708e 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ Set the following in config.yaml under inverters section. * Level: 2 - This should be everything your inverter supports * Level: 3 - This will try every register, you will get lots of 0/65535 responses for registers not supported. -* smart_meter: True - Set to true if you have a smart reader installed, this will return power usage at the meter box, without it you can not calculate house power usage. +* smart_meter: True - (_Only needed for SG* Models_) Set to true if you have a smart meter installed, this will return power usage at the meter box, without it you can not calculate house power usage. Hybrid inverters will provide this by default (load_power_hybrid) ### Useful Registers: This is just a brief list of registers I have found useful @@ -159,19 +159,23 @@ This is just a brief list of registers I have found useful **total_running_time** - Total Hours inverter has been powered on since install **internal_temperature** - Internal temperature of the Inverter **total_active_power** - Current power being generated by the inverter in Watts -**meter_power** - Power usage at the meter box, needs a smart meter installed. +ve means consuming from the grid, -ve means exporting to the grid +**meter_power** - (_SG* Models_)Power usage at the meter box, needs a smart meter installed. +ve means consuming from the grid, -ve means exporting to the grid **load_power** - Power being consumed in total -**export_to_grid** - How much being currently exported to the grid. This is calculated from meter_power if -ve value, returned as a positive value -**import_from_grid** - How much being currently imported from grid. This is calculated from meter_power if +ve value +**load_power_hybrid** - (_SH* Models only_) Power being consumed in total +**export_to_grid** - How much being currently exported to the grid. +For SG* Models this is calculated from meter_power if -ve value, returned as a positive value. (_For Hybrid models export_power_hybrid is used_) +**import_from_grid** - How much being currently imported from grid. This is calculated from meter_power if +ve value (_for hybrid models export_power_hybrid [will be negative when importing from grid] is used) **timestamp** - Last time data was collected, based on Inverters clock by default

(back to top)

## Home Assistant setup -In the SunGather config.yaml you need to set the smart_meter if you have one; +In the SunGather config.yaml you need to set the smart_meter if you have one +_For Hybrid Models smart_meter doesn't need to get enabled_ ``` +# Only for SG* Models smart_meter: True ``` @@ -221,6 +225,8 @@ Solar Panels > Solar Production -> Solar Production (Sungather) ## Tested * SG7.0RT with WiNet-S Dongle * SG10RT with WiNet-S Dongle and Ethernet (Credit: @rark-ha) +* SH6.0RT with WiNet-S Dongle +* SH10RT with WiNet-S Dongle

(back to top)

diff --git a/SunGather/sungather.py b/SunGather/sungather.py index a1355b9..285d500 100644 --- a/SunGather/sungather.py +++ b/SunGather/sungather.py @@ -325,10 +325,11 @@ class SungrowInverter(): # Create a registers for Power imported and exported to/from Grid if self.inverter_config['level'] >= 1: + self.latest_scrape["export_to_grid"] = 0 + self.latest_scrape["import_from_grid"] = 0 + if self.validateRegister('meter_power'): try: - self.latest_scrape["export_to_grid"] = 0 - self.latest_scrape["import_from_grid"] = 0 power = self.latest_scrape.get('meter_power', self.latest_scrape.get('export_power', 0)) if power < 0: self.latest_scrape["export_to_grid"] = abs(power) @@ -336,17 +337,15 @@ class SungrowInverter(): self.latest_scrape["import_from_grid"] = power except Exception: pass - # in this case we connected to a hybrid inverter and need to calculate the import differently + # in this case we connected to a hybrid inverter and need to use export_power_hybrid + # export_power_hybrid is negative in case of importing from the grid elif self.validateRegister('export_power_hybrid'): try: - self.latest_scrape['export_to_grid'] = self.latest_scrape.get('export_power_hybrid', 0) - self.latest_scrape['import_from_grid'] = 0 - - # take AC output of the inverter into account as could have a battery attached. - # once the load is higher then the AC output, we import energy from the grid - power = self.latest_scrape.get('load_power_hybrid') - self.latest_scrape('total_active_power') - if power > 0: - self.latest_scrape['import_from_grid'] = power + power = self.latest_scrape.get('export_power_hybrid', 0) + if power < 0: + self.latest_scrape["import_from_grid"] = abs(power) + elif power >= 0: + self.latest_scrape["export_to_grid"] = power except Exception: pass