Skip to content

Commit

Permalink
pypi0_9_3 update
Browse files Browse the repository at this point in the history
  • Loading branch information
britkat1980 committed Feb 2, 2022
1 parent e27e481 commit e78b30f
Show file tree
Hide file tree
Showing 16 changed files with 480 additions and 269 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
settings.py
src/settings.py
givenergy_modbus
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ settings.old
__pycache__
givtcp_debug.log
.venv
.vscode
.vscode
/givenergy_modbus
6 changes: 2 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RUN pip install -r requirements.txt

# copy the content of the local src directory to the working directory
COPY src/ .
ADD givenergy_modbus /usr/local/lib/python3.10/site-packages/givenergy_modbus

ENV INVERTOR_IP=""
ENV MQTT_OUTPUT="True"
Expand All @@ -23,7 +24,7 @@ ENV MQTT_PASSWORD=""
ENV MQTT_TOPIC=""
ENV MQTT_PORT="1883"
ENV JSON_OUTPUT="False"
ENV DEBUG="False"
ENV LOG_LEVEL="Error"
ENV DEBUG_FILE_LOCATION=""
ENV PRINT_RAW="False"
ENV SELF_RUN="True"
Expand All @@ -33,9 +34,6 @@ ENV INFLUX_URL=""
ENV INFLUX_TOKEN=""
ENV INFLUX_BUCKET=""
ENV INFLUX_ORG=""
ENV HA_OUTPUT="False"
ENV HA_URL=""
ENV HA_TOKEN=""

EXPOSE 6345 1883

Expand Down
122 changes: 53 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,40 @@ A settings.py file is required in the root directory. Use the supplied settings_
# Execution of GivTCP
GivTCP can be executed in a number of ways and can be set to output data in multiple formats. Exact usage is dependent on your use-case and needs:

| Method | Description |
| ---------------| ------------------------------- |
| [CLI](#cli-usage) | Execute the script at the command line and pass the relevant function and parameters as per the details below |
| [CLI through Node-Read](#cli-through-node-red) | Using the Exec node in Node-Red to call the script in the same way as above. This allows automation of script calling within a wider automated system |
| [REST Service](#restful-service) | Deployed inside a Docker container a RESTful service calls the relevant functions using the details below through GET and POST http methods |
| [Docker container](#docker) | A docker container is available which has all code and pre-requisites installed and out of the box is set to auto-discover the invertor and publish to an internal MQTT broker. This can be changed to publish to an external broker by modifying the container ENV variables |
Reccomended usage is through the Docker container found here: https://hub.docker.com/repository/docker/britkat/giv_tcp-ma
This will set up a self-running service which will publish data as required and provide a REST interface for control. An internal MQTT broker can be activiated to make data avalable on the network.


# Output formats:
## MQTT
The script will publish directly to the nominated MQTT broker all the requested read data.

<img width="245" alt="image" src="https://user-images.githubusercontent.com/69121158/149670766-0d9a6c92-8ee2-44d6-9045-2d21b6db7ebf.png">


## JSON
The functions return a JSON formated object which can then be consumed by other systems or functions, default output is to stdout

## InfluxDB
Publish Power and energy stats to your InfluxDB database using credentials you provide.

# GivTCP functions
## Read functions
GivTCP is able to retrieve key information from the GivEnergy Invertors through predefined functions:

### Available read functions are:
GivTCP collects all invertor ad battery data through the "runAll" function. It creates a nested data structure with all data available in a structured format.
Data Elements are:
*Energy - Today and all-time Total
*Power - Real-time stats and power flow data
*Invertor Details - Status details such as Serial Number
*Timeslots - Charge and Discharge
*Control - Charge/Discharge rates, Battery SOC
*Battery Details - Status and real-time cell voltages
* Energy - Today and all-time Total
* Today
* Total
* Power - Real-time stats and power flow data
* Power stats (eg. Import)
* Power Flow (eg. Grid to House)
* Invertor Details - Status details such as Serial Number
* Timeslots - Charge and Discharge
* Control - Charge/Discharge rates, Battery SOC
* Battery Details - Status and real-time cell voltages
* Battery 1
* Battery 2
* ...


## Control functions
Expand All @@ -68,58 +72,14 @@ Control is available through predefined functions. The format of the function ca
|setBatteryMode|{"mode":"1"}| Sets battery operation mode. Mode value must be in the range 1-4|
|setDateTime|{"dateTime":"dd/mm/yyyy hh:mm:ss"}| Sets invertor time, format must be as shown here|

# CLI Usage
GivTCP can be called from any machine running Python3. The relevant script must be called and a function name passed to it as an argument. Exmaples of how to call read and write functions are shown here:

## Read
`python3 read.py {{functionName}}`

The full call to get all information by running the runAll function would then be:

`python3 read.py runAll`

## Control
`python3 write.py {{functionName}} '{{controlPayload}}'`

An example payload can be found below.
Note: In order to send json payloads via CLI you will need to place the JSON string inside single quotes

The full call to set Charge Timeslot 1 would then be:

`python3 write.py setChargeSlot1 '{"enable": true,"start": "0100","finish": "0400","chargeToPercent": "100"}'`

# CLI through Node-Red

Node-Red provides the ability to call the python scripts through an "Exec" node. This essentially makes a command line call to the host OS, and mimics the CLI process above. The advantage of this execution method is that it allows integration into wider automation systems and provides a stable, self-healing ability to run the script on demand. wrapping this core code in a logic flow.

![image](https://user-images.githubusercontent.com/69121158/122303286-3bc7e000-cefb-11eb-93c5-bf48907bd189.png)

To execute this you must download the src files for this project, place them in an accessible folder on your machine running Node-Red then set the paramters of the Exec functon to call it.

Example Node-Red flows are vailable here: XXXX

# RESTful Service
GivTCP provides a wrapper function REST.py which uses Flask to expose the read and control functions as RESTful http calls. To utilise this service you will need to either use a WSGI serivce such as gunicorn or use the pre-built Docker container

## Gunicorn
Ensure Gunicorn is installed by running:

`pip install gunicorn`

Then call the service by initiating the following command from the same directory as the downloaded src files:

`gunicorn -w 4 -b 127.0.0.1:6345 REST:giv_api`

(where the 127.0.0.1:6345 is the IP address and port you want to bind the service to)

## Docker
# Docker
The docker container can be downloaded at the Docker hub here:
https://hub.docker.com/repository/docker/britkat/giv_tcp-ma

* Docker image is multi-architecture so docker should grab the correct version for your system (tested on x86 and rpi3)
* Create a container with the relevant ENV variables below (mimicing the settings.py file)
* Set the container to auto-restart to ensure reliability
* Out of the box the default setup enables local MQTT broker and REST service
* Out of the box the default setup enables local MQTT broker and REST service (see below for details)
* For Invertor autodiscovery to function your container must run on the "Host" network within docker (not Bridge). If it fails then you will need to manually add in INVERTOR_IP to the env variables

| ENV Name | Example | Description |
Expand All @@ -131,32 +91,34 @@ https://hub.docker.com/repository/docker/britkat/giv_tcp-ma
| MQTT_USERNAME | bob | Optional |
| MQTT_PASSWORD | cat | Optional |
| MQTT_TOPIC | GivEnergy/Data | Optional - default is Givenergy.<serial number>|
| DEBUG | False | Optional - if True then will write debug info to sepcified file location (default is same directory as the py files) |
| LOG_LEVEL | Error | Optional - you can choose Error, Info or Debug. Output will be sent to the debug file location if specified, otherwise it is sent to stdout|
| DEBUG_FILE_LOCATION | /usr/pi/data | Optional |
| PRINT_RAW | False | Optional - If set to True the raw register values will be returned alongside the normal data |
| INFLUX_OUTPUT | False | Optional - Used to enable publishing of energy and power data to influx |
| INFLUX_TOKEN |abcdefg123456789| Optional - If using influx this is the token generated from within influxdb itself |
| INFLUX_BUCKET |giv_bucket| Optional - If using influx this is data bucket to use|
| INFLUX_ORG |giv_tcp| Optional - If using influx this is the org that the token is assigned to |
| HA_OUTPUT | False |Optional - Used to enable publishing of energy and power data to Home Assistant |
| HA_URL |https://homeassistant.local:8123| URL of Home Assistant instance (noting correct use of IP or domain name, whichever works in your browser)|
| HA_TOKEN |abcdefg123456789| Optional - If using Home Assistant this is the Long Lasting Token generated from within Home Assistant itself |
| INFLUX_ORG |giv_tcp| Optional - If using influx this is the org that the token is assigned to |

# RESTful Service
GivTCP provides a wrapper function REST.py which uses Flask to expose the read and control functions as RESTful http calls. To utilise this service you will need to either use a WSGI serivce such as gunicorn or use the pre-built Docker container.

This can be used within a Node-Red flow to integrate into your automation or using Home Assistany REST sensors unsing the Home Assistant yaml package provided.
NB.This does require the Docker container running on your network.

### Calling RESTFul Functions
## Calling RESTFul Functions

The following table outlines the http methods needed to call the various read and control functions. For each control function the payload is an identical JSON string as above (minus the single quotes).
The RESTful Service will return a JSON object which you can then parse as you so desire

URL's below are based off the root http address of http://IP:6345
(Port may change if you are running yourself using gunicorn, in which case use the details specified in the gunicorn command)

#### Read Functions
### Read Functions
| URL | Method | payload |
| ------------------ | ------------ | -------------------- |
| /runAll| GET | None | |

#### Control Functions
### Control Functions
| URL | Method | payload |
| ------------------ | ------------ | -------------------- |
| /disableChargeTarget| POST | None |
Expand All @@ -173,3 +135,25 @@ URL's below are based off the root http address of http://IP:6345
| /setDischargeSlot2| POST | {"start":"0100","finish":"0400","dischargeToPercent":"55"} |
| /setBatteryMode| POST | {"mode":"1"} |
| /setDateTime|POST | {"dateTime":"dd/mm/yyyy hh:mm:ss"}|


## Gunicorn
If you don't wish to run the docker container, you can set up your own wysg application using Gunicorn/Flask.
Ensure Gunicorn is installed by running:

`pip install gunicorn`

Then call the service by initiating the following command from the same directory as the downloaded src files:

`gunicorn -w 4 -b 127.0.0.1:6345 REST:giv_api`

(where the 127.0.0.1:6345 is the IP address and port you want to bind the service to)

# CLI Usage
GivTCP can be called from any machine running Python3. The relevant script must be called and a function name passed to it as an argument.

An example payload can be found below.
Note: In order to send json payloads via CLI you will need to place the JSON string inside single quotes

The full call to set Charge Timeslot 1 would then be:
`python3 write.py setChargeSlot1 '{"enable": true,"start": "0100","finish": "0400","chargeToPercent": "100"}'`
42 changes: 0 additions & 42 deletions documentaion/APIDocumentation.md

This file was deleted.

Binary file removed documentaion/registersAndFunctions.xlsb.xlsx
Binary file not shown.
32 changes: 0 additions & 32 deletions documentaion/tutorial.md

This file was deleted.

Loading

0 comments on commit e78b30f

Please sign in to comment.