Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
ignore = E501,F405
import-order-style = appnexus
application-import-names = rpi_eco_light
65 changes: 63 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,63 @@
*.pyc
*.swp
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/

#Ipython Notebook
.ipynb_checkpoints
13 changes: 13 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
language: python
python:
- "2.7"

install:
- pip install tox-travis

script: tox

deploy:
provider: pypi
repository: https://pypi.fury.io/geben/
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my account on https://gemfury.com/
You can either set up your own account. Use my referral: https://www.fury.co/r/WbX2giralw

or you can upload this package to https://pypi.org/ only doing that you need to be more careful about package versioning in case someone uses it.

password: '2fGzvp-gDf95Ygur9Hl5oaPOLD1L0NKYdM'
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this repo is pubic this password is disabled, You can encrypt secrets in Travis https://docs.travis-ci.com/user/encryption-keys/

4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include requirements.txt
graft rpi_eco_light/example_conf
global-exclude __pycache__
global-exclude *.py[co]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# rpi-eco-light
Raspberry Pi based Owl Energy Monitor Light Indicator

The 'bin' and 'etc' directories are a direct copy of the 'bin' and 'etc' directories from: https://github.com/cornetp/eagle-owl
Requires: https://github.com/cornetp/eagle-owl
4 changes: 0 additions & 4 deletions TODO

This file was deleted.

Binary file removed bin/arm/cm160
Binary file not shown.
Binary file removed bin/arm/db_import
Binary file not shown.
Binary file removed bin/i386/cm160
Binary file not shown.
Binary file removed bin/i386/db_import
Binary file not shown.
7 changes: 0 additions & 7 deletions etc/eagleowl.conf

This file was deleted.

22 changes: 0 additions & 22 deletions etc/init/cm160.conf

This file was deleted.

9 changes: 0 additions & 9 deletions etc/init/rpi-eco-light.conf

This file was deleted.

62 changes: 0 additions & 62 deletions install.sh

This file was deleted.

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
unicornhat==2.2.3
7 changes: 7 additions & 0 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
flake8==3.7.4
flake8-import-order==0.18
flake8-mutable==1.2.0
flake8-quotes==1.0.0
flake8-tuple==0.2.13
mock==2.0.0
pytest==4.2.0
1 change: 1 addition & 0 deletions rpi_eco_light/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '0.0.1'
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when you want to make a new version you just increase this number and commit

File renamed without changes.
11 changes: 11 additions & 0 deletions rpi_eco_light/conf/conf_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ConfigParser


class ConfigHelper(object):
def __init__(self, config_file):
self._config_file_location = config_file

def get_current_config(self):
config = ConfigParser.ConfigParser()
config.read(self._config_file_location)
return config
File renamed without changes.
28 changes: 18 additions & 10 deletions src/db_comms.py → rpi_eco_light/db_comms.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import logging
import os
import time
import logging


class DBComms:
def __init__(self, db_location):
class DBComms(object):
def __init__(self, config_helper):
self._logger = logging.getLogger(self.__class__.__name__)
self._db_location = db_location
self._live_location = ".live"
self._config_helper = config_helper
self._live_location = '.live'
self._last_update_time = None
self._update_checks = 0
self._max_update_checks = 10

@property
def _current_config(self):
return self._config_helper.get_current_config()

def _db_file(self):
return '{}/{}'.format(self._current_config.get('service', 'db_path'), self._live_location)

def get_current_kw(self):
with open("{}/{}".format(self._db_location,
self._live_location),
"r") as live_file:
with open(self._db_file(), 'r') as live_file:
line = live_file.readline()
splits = line.split()
kw = 0
Expand All @@ -27,7 +32,8 @@ def get_current_kw(self):

def check_comms_status(self):
comms_good = True
temp_last_update_time = time.ctime(os.path.getmtime(self._db_location + "/" + self._live_location))
self._max_update_checks = self._current_config.get('service', 'max_update_checks')
temp_last_update_time = time.ctime(os.path.getmtime(self._db_file()))
if not self._last_update_time:
# not initialised
self._last_update_time = temp_last_update_time
Expand All @@ -41,6 +47,8 @@ def check_comms_status(self):
self._update_checks += 1
if self._update_checks >= self._max_update_checks:
# We've reached our max attempts to query - something's gone wrong
self._logger.error("Max update checks reached, last update time: %s" % temp_last_update_time)
self._logger.error('Max update checks reached, last update time: {!s}'.format(temp_last_update_time))
comms_good = False
else:
self._logger.debug('Value has not been updated in {:d} queries, max queries before error: {:d}'.format(self._update_checks, self._max_update_checks))
return comms_good
43 changes: 43 additions & 0 deletions rpi_eco_light/eco_light.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import argparse
import logging.config
import signal
import sys
import time

from rpi_eco_light.conf.conf_helper import ConfigHelper
from rpi_eco_light.conf.logging import LOGGING
from rpi_eco_light.energy_usage_light import EnergyUsageLight

logging.config.dictConfig(LOGGING)
logger = logging.getLogger(__name__)


def signal_term_handler(signal, frame):
logger.fatal('Handling SIGTERM')
sys.exit(0)


def run_eco_light():
parser = argparse.ArgumentParser()
parser.add_argument('config_file', help='The config file to use')
args = parser.parse_args()

logger.info('Starting RPi ECO Light - config: {}'.format(args.config))
config_helper = ConfigHelper(args.config)
signal.signal(signal.SIGINT, signal_term_handler)
usage_light = EnergyUsageLight(config_helper)
while True:
current_config = config_helper.get_current_config()
LOGGING['handlers']['console']['level'] = current_config.get('service', 'log_level')
logging.config.dictConfig(LOGGING)

usage_light.update()
# Flush the stdout each time round the loop
sys.stdout.flush()

# Sleep for a bit before the next update
time.sleep(float(current_config.get('service', 'update_interval_in_sec')))


if __name__ == '__main__':
run_eco_light()
67 changes: 67 additions & 0 deletions rpi_eco_light/energy_usage_light.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import logging

from db_comms import DBComms
from lighting import Lighting


logger = logging.getLogger(__name__)


def kw_to_rgb(kw, current_config):
"""
Converts Power (KW) to a RGB value
:param kw: power
:param current_config: the current configuration file
:return: a tuple for RGB values
"""
lighting_value = kw
if current_config.get('monitor', 'type') == 'PENCE':
lighting_value = current_config.getfloat('monitor', 'cost_per_hour_in_pence') * kw
logger.debug('KW in pence: %s' % lighting_value)
else:
logger.debug('KW: %s' % lighting_value)

level_1 = current_config.getfloat('levels', 'level_1')
level_2 = current_config.getfloat('levels', 'level_2')
level_3 = current_config.getfloat('levels', 'level_3')
level_4 = current_config.getfloat('levels', 'level_4')

if lighting_value >= level_4:
logger.debug('>= {:.2f} = RED'.format(level_4))
rgb_value = Lighting.RED
elif lighting_value >= level_3:
logger.debug('< {:.2f} && >= {:.2f} = ORANGE'.format(level_4, level_3))
rgb_value = Lighting.ORANGE
elif lighting_value >= level_2:
logger.debug('< {:.2f} && >= {:.2f} = YELLOW'.format(level_3, level_2))
rgb_value = Lighting.YELLOW
elif lighting_value >= level_1:
logger.debug('< {:.2f} && >= {:.2f} = GREEN'.format(level_2, level_1))
rgb_value = Lighting.GREEN
elif 0 < lighting_value < level_1:
logger.debug('< {:.2f} = BLUE'.format(level_1))
rgb_value = Lighting.BLUE
elif lighting_value == 0:
logger.debug('==0 = PURPLE (No value yet)')
rgb_value = Lighting.PURPLE
else:
rgb_value = Lighting.GREEN

return rgb_value


class EnergyUsageLight(object):
def __init__(self, config_helper):
self._config_helper = config_helper
self._comms = DBComms(config_helper)
self._light = Lighting()

def update(self):
current_config = self._config_helper.get_current_config()

if not self._comms.check_comms_status():
self._light.set_error()
else:
kw = self._comms.get_current_kw()
rgb_dict = kw_to_rgb(kw, current_config)
self._light.set_light(rgb_dict)
Loading