12 Commits

Author SHA1 Message Date
95e856f5f7 try another kaniko builder
Some checks failed
Build and push container / Container-Build (push) Failing after 2m12s
2024-07-28 14:26:07 +02:00
99f0c12455 disabled demo action 2024-07-28 14:25:57 +02:00
6b2ad223c7 separate tag
Some checks failed
Build and push container / Container-Build (push) Failing after 46s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 38s
2024-07-27 16:04:11 +02:00
0330fddaf1 just ref
Some checks failed
Build and push container / Container-Build (push) Failing after 52s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 51s
2024-07-27 16:00:59 +02:00
399cce6a2e push only
Some checks failed
Build and push container / Container-Build (push) Failing after 2m5s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 39s
2024-07-27 15:56:19 +02:00
94be339a0a indents from hell
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 50s
2024-07-27 15:53:17 +02:00
5069cfa039 fixes
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2024-07-27 15:52:43 +02:00
7ef9c4e614 ga: autobulding containers
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 40s
2024-07-27 15:48:39 +02:00
17e8a90f40 typo fix
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 47s
2024-07-27 15:29:36 +02:00
edcde52192 move GA to proper place
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m55s
2024-07-27 15:23:12 +02:00
15d2634186 demo GA 2024-07-27 15:20:57 +02:00
09da459a53 add Containerfile for pbrk deployments 2024-07-27 15:15:35 +02:00
8 changed files with 94 additions and 55 deletions

View File

@@ -0,0 +1,24 @@
---
name: Build and push container
run-name: Container creation
# change later for only tags
on: [push]
jobs:
Container-Build:
runs-on: ubuntu-latest
steps:
- name: Get the code
uses: actions/checkout@v4
with:
sparse-checkout: |
src
- name: Build & push image ${{ gitea.ref }}
uses: bymarshall/kaniko-action@main
with:
image: ha-addon-energa-meter
tag: ${{ gitea.ref }}
registry: pipebreaker.pl:5000
file: Containerfile
context: src/
debug_mode: true

View File

@@ -0,0 +1,22 @@
name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out GA 🍆
on: [push]
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- name: Checkout code
uses: actions/checkout@v3
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files
run: |
echo ${{ gitea.workspace }}:
ls ${{ gitea.workspace }}
- run: echo "🍏 This job's status is ${{ gitea.status }}."

23
src/Containerfile Normal file
View File

@@ -0,0 +1,23 @@
FROM fedora-minimal:latest
RUN microdnf install -y python3-pip && pip install uv
WORKDIR /app
COPY requirements.txt .
RUN uv venv /app/venv && \
source /app/venv/bin/activate && \
uv pip install -r requirements.txt
# Copy data for add-on
COPY database_empty.sqlite data/database.sqlite
COPY rund.sh .
COPY run.py .
COPY main.py .
COPY api.py .
COPY moj_licznik.py .
COPY log_config.py .
RUN chmod a+x rund.sh
CMD [ "/app/rund.sh" ]

View File

@@ -13,7 +13,7 @@ COPY main.py .
COPY api.py .
COPY moj_licznik.py .
COPY log_config.py .
COPY database_empty.sqlite data/database.sqlite
COPY database_empty.sqlite database.sqlite
RUN chmod a+x run.sh
RUN apk add --update --no-cache py3-pip && \

View File

@@ -47,11 +47,6 @@ Wymagane parametry:
* ENERGA_USERNAME - nazwa użytkownika w aplikacji Energa Mój licznik
* ENERGA_PASSWORD - hasło użytkownika w aplikacji Energa Mój licznik
Opcjonalne parametry:
* POSTGRESQL_CONNSTRING - namiar na bazę PostgreSQL do przechowywania odczytów;
format opisany w [dokumentacji PGSQL](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING-URIS)
(przykładowo `postgresql://uzytkownik:haslo@serwer/mojlicznik`)
## Konfiguracja sensorów
Do HA możesz dodać sensory, które zawierają informacje udostępniane przez API

View File

@@ -1,4 +1,4 @@
from peewee import SqliteDatabase, PostgresqlDatabase
from peewee import SqliteDatabase
from flask import Flask, jsonify, request, redirect, url_for, abort
from waitress import serve
#from datetime
@@ -9,30 +9,13 @@ import urllib.parse
logger = logging.getLogger("energaMeter.api")
if postgresql_connstring := os.getenv("POSTGRESQL_CONNSTRING"):
from psycopg2.extensions import parse_dsn
db_name = parse_dsn(postgresql_connstring)['dbname']
db = PostgresqlDatabase(db_name, dsn=postgresql_connstring)
else:
path = os.path.dirname(os.path.abspath(__file__))
db_file = 'data/database.sqlite'
db = SqliteDatabase(os.path.join(path, db_file))
path = os.path.dirname(os.path.abspath(__file__))
db_file = 'database.sqlite'
db = SqliteDatabase(os.path.join(path, db_file))
app = Flask(__name__)
# This hook ensures that a connection is opened to handle any queries
# generated by the request.
@app.before_request
def _db_connect():
db.connect()
# This hook ensures that the connection is closed when we've finished
# processing the request.
@app.teardown_request
def _db_close(exc):
if not db.is_closed():
db.close()
@app.route('/', methods=['GET'])
def root():
query = PPETable.select() #.where(PPETable.is_active == True)
@@ -224,7 +207,7 @@ def charts():
zone = request.args.get('zone', None)
negative = request.args.get('negative', type=bool, default=False)
logger.debug(f"API: GET /charts - {start_date} - {end_date}")
query = MainChartTable.select().where((MainChartTable.tm >= int(start_date)/1000) & (MainChartTable.tm <= int(end_date)/1000))
query = MainChartTable.select().where((MainChartTable.tm >= int(start_date)) & (MainChartTable.tm <= int(end_date)))
logger.debug(f"{query}")
factor = 1
if negative:
@@ -243,13 +226,13 @@ def charts():
charts = []
for p in result_ppes:
czas = p.tm.strftime("%Y-%m-%d %H:%M:%S")
czas = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(p.tm/1000))
chart = {
'mp': p.mp,
'meter_type': p.meter_type,
'meter_type_url': urllib.parse.quote_plus(p.meter_type),
'zone': p.zone,
'time_tm': int(p.tm.timestamp()*1000),
'time_tm': p.tm,
'time': czas,
'value': p.value * factor
}

View File

@@ -1,25 +1,18 @@
from peewee import SqliteDatabase, PostgresqlDatabase
from peewee import SqliteDatabase
from datetime import datetime, timedelta, date
import calendar, requests, re, time, json, os, logging
import http.cookiejar as cookiejar
from requests.exceptions import HTTPError
from bs4 import BeautifulSoup
from enum import Enum
from peewee import AutoField, Model, CharField, IntegerField, DateField, BooleanField, CompositeKey, DecimalField, ForeignKeyField, SQL, TextField, TimestampField
from peewee import AutoField, Model, CharField, IntegerField, DateField, BooleanField, CompositeKey, DecimalField, ForeignKeyField, SQL
import urllib.parse
logger = logging.getLogger("energaMeter")
if postgresql_connstring := os.getenv("POSTGRESQL_CONNSTRING"):
from psycopg2.extensions import parse_dsn
db_name = parse_dsn(postgresql_connstring)['dbname']
db_host = parse_dsn(postgresql_connstring)['host']
db = PostgresqlDatabase(db_name, dsn=postgresql_connstring)
logger.info(f"Używam bazy PostgreSQL „{db_name}” na {db_host}")
else:
path = os.path.dirname(os.path.abspath(__file__))
db_file = 'data/database.sqlite'
db = SqliteDatabase(os.path.join(path, db_file))
path = os.path.dirname(os.path.abspath(__file__))
db_file = 'database.sqlite'
db = SqliteDatabase(os.path.join(path, db_file))
class ChartType(Enum):
DAY = "DAY"
@@ -38,7 +31,7 @@ class PPETable(Model):
class Meta:
database = db
table_name = 'PPE'
constraints = [SQL('UNIQUE ("ppe", "tariffCode")')]
constraints = [SQL('UNIQUE (ppe, tariffCode)')]
class MeterTable(Model):
id = AutoField() # Meter point
@@ -50,7 +43,7 @@ class MeterTable(Model):
class Meta:
database = db
table_name = 'METER'
constraints = [SQL('UNIQUE ("ppe_id", "meter_type")')]
constraints = [SQL('UNIQUE (ppe_id, meter_type)')]
class CounterTable(Model):
id = AutoField()
@@ -78,7 +71,7 @@ class ChartTable(Model):
year = IntegerField()
month = IntegerField(null=True)
day = IntegerField(null=True)
value = TextField()
value =CharField()
class Meta:
database = db
@@ -89,7 +82,7 @@ class MainChartTable(Model):
mp = CharField()
meter_type = CharField()
zone = IntegerField()
tm = TimestampField()
tm = IntegerField()
value = DecimalField(max_digits=20, decimal_places=16, null=True)
tarAvg = DecimalField(max_digits=20, decimal_places=16, null=True)
est = BooleanField(default=False)
@@ -367,17 +360,16 @@ class MojLicznik:
try:
logger.debug(f"save_main_charts: mp: {mp}, val: {val}, meter_type: {m_type}")
z = val["zones"]
tm = int(val["tm"]) / 1000 # convert JS timestamp (milliseconds) to unix (seconds)
if z[0]:
# MainChartTable.get_or_create(tm = val["tm"], zone = 1, value = z[0], tarAvg=val["tarAvg"], est=val["est"], cplt=val["cplt"])
try:
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == tm) & (MainChartTable.zone == 1))
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == val["tm"]) & (MainChartTable.zone == 1))
except MainChartTable.DoesNotExist:
# Jeśli rekord nie istnieje, utwórz nowy
MainChartTable.create(
mp=mp,
meter_type=m_type,
tm=tm,
tm=val["tm"],
zone=1,
value=z[0],
tarAvg=val["tarAvg"],
@@ -387,13 +379,13 @@ class MojLicznik:
if z[1]:
try:
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == tm) & (MainChartTable.zone == 2))
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == val["tm"]) & (MainChartTable.zone == 2))
except MainChartTable.DoesNotExist:
# Jeśli rekord nie istnieje, utwórz nowy
MainChartTable.create(
mp=mp,
meter_type=m_type,
tm=tm,
tm=val["tm"],
zone=2,
value=z[1],
tarAvg=val["tarAvg"],
@@ -403,13 +395,13 @@ class MojLicznik:
if z[2]:
try:
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == tm) & (MainChartTable.zone == 3))
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == val["tm"]) & (MainChartTable.zone == 3))
except MainChartTable.DoesNotExist:
# Jeśli rekord nie istnieje, utwórz nowy
MainChartTable.create(
mp=mp,
meter_type=m_type,
tm=tm,
tm=val["tm"],
zone=3,
value=z[2],
tarAvg=val["tarAvg"],

Binary file not shown.