Skip to content

Commit

Permalink
Merge pull request #2 from maexled/folder-structure
Browse files Browse the repository at this point in the history
created folder structure
  • Loading branch information
maexled authored May 29, 2022
2 parents 847f161 + 481a27c commit abcc88d
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 59 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir -r requirements.txt

COPY . .
CMD ["python", "./main.py"]
CMD ["python", "-m", "main"]
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,19 @@
Requests data from MyStrom switch and stores in sql database.

## Environment Variables
`SQL_URL` - the URL for database, e.g. `mysql+pymysql://user:password@host:3306/databsae`
`SQL_URL` - the URL for database, e.g. `mysql+pymysql://user:password@host:3306/database`

## Run
### With python
```sh
export SQL_URL=mysql+pymysql://user:password@host:3306/database
python -m main
```

### With Docker Container
```sh
docker run \
--name mystrom-python \
-e "SQL_URL=mysql+pymysql://user:password@host:3306/database" \
ghcr.io/maexled/mystrom-python:master
```
17 changes: 17 additions & 0 deletions base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

sql_url = os.environ['SQL_URL']
engine = create_engine(sql_url)
# use session_factory() to get a new Session
_SessionFactory = sessionmaker(bind=engine)

Base = declarative_base()


def session_factory():
Base.metadata.create_all(engine)
return _SessionFactory()
66 changes: 9 additions & 57 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,16 @@
import schedule
import time
from datetime import datetime, timezone, timedelta
import requests
import json
import os

from sqlalchemy import Column, Integer, Float, String, DateTime, ForeignKey
import sqlalchemy as db
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref, sessionmaker, joinedload
import threading

Base = declarative_base()
from base import Base, session_factory

class MystromDevice(Base):

__tablename__ = 'devices'

id = Column(Integer, primary_key=True)

name = Column(String(16))
ip = Column(String(16))

# Lets us print out a user object conveniently.
def __repr__(self):
return "<Device(id='%s', name='%s', ip='%s')>" % (
self.id, self.name, self.ip)

class MystromResult(Base):

__tablename__ = 'results'

id = Column(Integer, primary_key=True)

device_id = Column(Integer, ForeignKey('devices.id'))

power = Column(Float)
ws = Column(Float)
relay = Column(Integer)
temperature = Column(Float)
date = Column(DateTime(timezone=True), default=datetime.now)

# Lets us print out a user object conveniently.
def __repr__(self):
return "<Result(deivce_id='%s', power='%s', ws='%s', relay='%s', temperature='%s', date='%s')>" % (
self.device_id, self.power, self.ws, self.relay, self.temperature, self.date)
from models.mystrom_device import MystromDevice
from models. mystrom_result import MystromResult

@schedule.repeat(schedule.every(1).minutes)
def trigger():
for device in devices:
request_data_and_store(device)
Expand All @@ -55,32 +21,18 @@ def get_devices():

def request_data_and_store(device):
response = requests.get(f'http://{device.ip}/report')
json_response = json.loads(response.text)
mystrom_result = json_result_to_object(json_response, device)
response = json.loads(response.text)
mystrom_result = MystromResult(device_id=device.id, power=response["power"], ws=response["Ws"], relay=response["relay"], temperature=response["temperature"])

session.add(mystrom_result, device)
session.commit()

def json_result_to_object(json, device):
return MystromResult(device_id=device.id, power=json["power"], ws=json["Ws"], relay=json["relay"], temperature=json["temperature"])

if __name__ == '__main__':
sql_url = os.environ['SQL_URL']
engine = db.create_engine(sql_url)
connection = engine.connect()

Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

session = session_factory()
devices = get_devices()

schedule.every(1).minutes.do(trigger)

while True:

# Checks whether a scheduled task
# is pending to run or not
schedule.run_pending()
time.sleep(1)
time.sleep(1)
16 changes: 16 additions & 0 deletions models/mystrom_device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from base import Base
from sqlalchemy import Column, Integer, String

class MystromDevice(Base):

__tablename__ = 'devices'

id = Column(Integer, primary_key=True)

name = Column(String(16))
ip = Column(String(16))

# Lets us print out a user object conveniently.
def __repr__(self):
return "<Device(id='%s', name='%s', ip='%s')>" % (
self.id, self.name, self.ip)
22 changes: 22 additions & 0 deletions models/mystrom_result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from base import Base
from sqlalchemy import Column, Integer, Float, DateTime, ForeignKey
from datetime import datetime

class MystromResult(Base):

__tablename__ = 'results'

id = Column(Integer, primary_key=True)

device_id = Column(Integer, ForeignKey('devices.id'))

power = Column(Float)
ws = Column(Float)
relay = Column(Integer)
temperature = Column(Float)
date = Column(DateTime(timezone=True), default=datetime.now)

# Lets us print out a user object conveniently.
def __repr__(self):
return "<Result(deivce_id='%s', power='%s', ws='%s', relay='%s', temperature='%s', date='%s')>" % (
self.device_id, self.power, self.ws, self.relay, self.temperature, self.date)

0 comments on commit abcc88d

Please sign in to comment.