Esempio n. 1
0
def get_encryption_key(key_file=None):
    """
    Encryption key for symmetric encryption. URL-safe base64-encoded 32-byte key

    * Get local key, or exec wizard for making one.

    :param: key_file: :str: path of the file with the encryption key
    :return: :bytes: encryption_key
    """

    if key_file is None:
        key_file = os.path.join(DATA_PATH, CONFIG.get('BROADCAST', 'KEY_FILE', fallback='.secret_key'))
    try:
        secret_key = open(key_file).read().encode()
    except FileNotFoundError:
        print('\033[0m\033[1m\033[34mCrypto KEY is missing.\033[0m Please, select one option:\n'
              '\t\033[1m1. Generate a new key.\n\t2. Input an existent key. (Copy&paste from another computer)')
        selec = input('\033[34mOPTION: \033[0m\033[31m')
        if selec == '1':
            secret_key = Fernet.generate_key()
        else:
            secret_key = input('*** KEY: ').encode()
        if len(secret_key) > 10:
            print('\033[0mThe new KEY ("{}")\nwill be saved in "{}"\n'.format(secret_key, key_file))
            open(key_file, 'wb').write(secret_key)
        else:
            print('\033[31;1mNot a valid KEY!:\n"{}". Try again... BYE!\033[0m'.format(secret_key))
            sys.exit(-1)
    return secret_key
Esempio n. 2
0
    def test_main_cli_data_plots(self):
        """
        CLI Testing patching sys.argv with unittest.mock

        """
        from enerpi.command_enerpi import enerpi_main_cli
        from enerpi.base import CONFIG

        dir_plots = os.path.join(self.DATA_PATH, CONFIG.get('ENERPI_DATA', 'IMG_BASEPATH'))
        self.exec_func_with_sys_argv(enerpi_main_cli,
                                     ['test_cli', '-f', '2016-10-01::2016-10-01', '-p', 'png', '-po', 'rm=30s'],
                                     test_mode=True)
        self.exec_func_with_sys_argv(enerpi_main_cli,
                                     ['test_cli', '-f', '::2016-10-04', '-p', 'png', '-po', 'rm=1h'],
                                     test_mode=True)
        self.exec_func_with_sys_argv(enerpi_main_cli,
                                     ['test_cli', '-f', '2016-10-25::2016-10-26', '-p', 'png', '-po', 'rs=30s'],
                                     test_mode=True)
        self.exec_func_with_sys_argv(enerpi_main_cli,
                                     ['test_cli', '-f', '2016-10-25::2016-10-30', '-p', 'png', '-po', 'rs=3min'],
                                     test_mode=True)
        self.exec_func_with_sys_argv(enerpi_main_cli,
                                     ['test_cli', '-f', '2016-10-21::2016-10-31', '-p', 'png', '-po', 'rs=30min'],
                                     test_mode=True)
        self.exec_func_with_sys_argv(enerpi_main_cli,
                                     ['test_cli', '-f', '2016-10-10::2016-10-30', '-p', 'png', '-po', 'rs=15min'],
                                     test_mode=True)
        # To get the plots for inspection:
        # os.system('cp -R {}/ ~/Desktop/test_plots'.format(dir_plots))
        self.assertEqual(len(os.listdir(dir_plots)), 6)
Esempio n. 3
0
def make_cron_command_task_daemon():
    """
    CRON periodic task for exec ENERPI LOGGER as daemon at every boot
    Example command:
    */15 * * * * sudo -u www-data /home/pi/PYTHON/py35/bin/python
        /home/pi/PYTHON/py35/lib/python3.5/site-packages/enerpiweb/mule_rscgen.py -o

    :return: :str: cron_command
    """
    # cmd_logger = '@reboot sudo -u {user_logger} {python_pathbin}/enerpi-daemon start'
    cmd_logger = 'sudo -u {user_logger} {python_pathbin}/enerpi-daemon start'
    local_params = dict(user_logger=CONFIG.get('ENERPI_DATA', 'USER_LOGGER', fallback='pi'),
                        python_pathbin=os.path.dirname(sys.executable))
    return cmd_logger.format(**local_params)
Esempio n. 4
0
def test_www_data_in_rpi():
    """
    Test for check user & groups membership needed to run ENERPI with:
        · The ENERPI logger daemon, running every reboot with CRON
        · The ENERPI flask webserver, running under NGINX + UWSGI-EMPEROR

    """
    from enerpi.base import CONFIG

    def _formatted_test(user_t, groups_t, fix=False):
        print('*' * 80 + '\nTEST (u="{}", g="{}", fix=False):'.format(user_t, groups_t))
        res = _check_user_groups(user=user_t, desired_groups=groups_t, fix=fix)
        print('********** TEST RESULT = {} **********'.format(res) + '\n' + '*' * 80)
        return res

    if sys.platform == 'linux':  # RPI only test
        user_logger = CONFIG.get('ENERPI_DATA', 'USER_LOGGER', fallback='www-data')
        user_web = CONFIG.get('ENERPI_WEBSERVER', 'USER_SERVER', fallback='www-data')

        needed_groups = [('spi', ), ('gpio', 'kmem')]
        for user in [user_logger, user_web]:
            print('\nCHECKING GROUPS MEMBERSHIP FOR USER "{}"'.format(user))
            groups_exist = _checkoutput(['groups'])[1].split()
            user_exists, user_groups = _get_user_groups(user)
            print('EXISTENT GROUPS: "{}"'.format(groups_exist))
            print('GROUPS WITH USER {} (exist={}): "{}"'.format(user, user_exists, user_groups))
            assert user_exists
            for need in needed_groups:
                print('need: {}'.format(need))
                for g in need:
                    print('analysis g={}'.format(g))
                    if g in groups_exist:
                        print('{} in groups_exist'.format(g))
                        result = _formatted_test(user, [g], fix=True)
                        print('user: {} in group: {}? {}--> '.format(user, g, result))
                        assert result
                        break
Esempio n. 5
0
def _get_pb_obj():
    # Lazy load
    global PBOBJ

    if PBOBJ is None:
        try:
            pushbullet_token = CONFIG.get('NOTIFY', 'PUSHBULLET_TOKEN')
            if not pushbullet_token:
                raise InvalidKeyError
            PBOBJ = Pushbullet(pushbullet_token)
        except (NoOptionError, NoSectionError, InvalidKeyError) as e:
            log('NO Pushbullet config ({} [{}])'
                .format(e, e.__class__), 'error', False)
            PBOBJ = None
    return PBOBJ
Esempio n. 6
0
    def test_1_streaming(self):

        def _print_next_msg(counter, iterator):
            msg = next(iterator)
            print('** STREAM MSG {}:\n{}\n --> T_{:.3f} secs'.format(counter, msg, time() - tic))

        tic = time()
        r = self.endpoint_request('api/stream/realtime', mimetype_check='text/event-stream', status_check=200)
        print('headers={}\nmimetype={}'.format(r.headers, r.mimetype))
        assert r.is_streamed
        assert not r.stream.closed
        toc_get = time()
        print('GET took {:.4f} s'.format(toc_get - tic))

        print('En STREAMING, DATA_PATH:{}, listdir:\n{}'.format(self.DATA_PATH, os.listdir(self.DATA_PATH)))
        from enerpi.base import CONFIG
        key_file_now = os.path.join(self.DATA_PATH, CONFIG.get('BROADCAST', 'KEY_FILE', fallback='.secret_key'))
        print('KEY_FILE_now: {}'.format(key_file_now))
        try:
            print('KEY_now: {}'.format(open(key_file_now).read()))
        except FileNotFoundError as e:
            # Problema de .secret_key ya importada!
            print(e)

        it = r.stream.response.iter_encoded()
        counter_received = 0
        for i in range(math.ceil(1.5 * self.stream_max_time)):
            try:
                _print_next_msg(i, it)
                counter_received += 1
            except StopIteration as e:
                print(e.__class__)
        self.assertGreater(counter_received, 1)
        assert not r.stream.closed
        r.stream.close()
        assert r.stream.closed
Esempio n. 7
0
def get_encryption_key(key_file=None):
    """
    Encryption key for symmetric encryption. URL-safe base64-encoded 32-byte key

    * Get local key, or exec wizard for making one.

    :param: key_file: :str: path of the file with the encryption key
    :return: :bytes: encryption_key
    """

    if key_file is None:
        key_file = os.path.join(
            DATA_PATH,
            CONFIG.get('BROADCAST', 'KEY_FILE', fallback='.secret_key'))
    try:
        secret_key = open(key_file).read().encode()
    except FileNotFoundError:
        print(
            '\033[0m\033[1m\033[34mCrypto KEY is missing.\033[0m Please, select one option:\n'
            '\t\033[1m1. Generate a new key.\n\t2. Input an existent key. (Copy&paste from another computer)'
        )
        selec = input('\033[34mOPTION: \033[0m\033[31m')
        if selec == '1':
            secret_key = Fernet.generate_key()
        else:
            secret_key = input('*** KEY: ').encode()
        if len(secret_key) > 10:
            print('\033[0mThe new KEY ("{}")\nwill be saved in "{}"\n'.format(
                secret_key, key_file))
            open(key_file, 'wb').write(secret_key)
        else:
            print(
                '\033[31;1mNot a valid KEY!:\n"{}". Try again... BYE!\033[0m'.
                format(secret_key))
            sys.exit(-1)
    return secret_key
Esempio n. 8
0
                         show_pi_temperature, set_logging_conf, log,
                         FILE_LOGGING, LOGGING_LEVEL)
from enerpi.database import init_catalog, save_raw_data, HDF_STORE_PATH
from enerpi.pisampler import enerpi_sampler_rms, enerpi_raw_sampler, msg_to_dict, tuple_to_dict_json
from enerpi.iobroadcast import get_codec, broadcast_msg, receiver_msg_generator
from enerpi.ledrgb import get_rgbled, led_info, led_alarm, blink_color
from enerpi.notifier import push_enerpi_error

# Disk data store
N_SAMPLES_BUFFER_DISK = CONFIG.getint('ENERPI_DATA',
                                      'N_SAMPLES_BUFFER_DISK',
                                      fallback=60)
STORE_PERIODIC_CATALOG_SEC = CONFIG.getint('ENERPI_DATA',
                                           'STORE_PERIODIC_CATALOG_SEC',
                                           fallback=3600)
INIT_LOG_MARK = CONFIG.get('ENERPI_SAMPLER', 'INIT_LOG_MARK', fallback='INIT')

# Variable global para controlar el estado de notificaciones vía RGB LED
LED_STATE = 0

PALETA = dict(off=(0., (0., 0., 1.)),
              standby=(250., (0., 1., 0.)),
              medium=(750., (1., .5, 0.)),
              high=(3500., (1., 0., 0.)),
              max=(4500., (1., 0., 1.)))

# Decay control
# (# of samples/s dropping a lot sometimes
#       --> y = -a * x**2. x(9:32)=1300, x(9:37)=1190, x(9:48)=995)
MIN_N_SAMPLES_DELTA_FRACTION = .5
MIN_N_SAMPLES_MAX_CONSIDERED = 900
Esempio n. 9
0
- Process or clear log files
- Method for appending raw data to ENERPI catalog from the ENERPI Logger
...

"""
import datetime as dt
import os
import pandas as pd
from time import time
import re
from enerpi.base import CONFIG, DATA_PATH, log, timeit, SENSORS
from enerpi.catalog import EnerpiCatalog


# Config:
INIT_LOG_MARK = CONFIG.get('ENERPI_SAMPLER', 'INIT_LOG_MARK', fallback='INIT ENERPI')
HDF_STORE = CONFIG.get('ENERPI_DATA', 'HDF_STORE')
HDF_STORE_PATH = os.path.join(DATA_PATH, HDF_STORE)

KEY = CONFIG.get('ENERPI_DATA', 'KEY', fallback='/rms')
CONFIG_CATALOG = dict(raw_file=HDF_STORE,
                      key_raw_data=KEY,
                      key_summary_data='/hours',
                      key_summary_extra='/days',
                      check_integrity=True,
                      archive_existent=False,
                      verbose=False)


def init_catalog(sensors=None, base_path=DATA_PATH, **kwargs):
    """
Esempio n. 10
0
# -*- coding: utf-8 -*-
"""
ENERPI - Broadcast receiver & emitter

"""
from cryptography.fernet import Fernet, InvalidToken
from binascii import Error
import os
import socket
import sys
from time import time
from enerpi.base import DATA_PATH, CONFIG, log

# LAN broadcasting
_UDP_IP = CONFIG.get('BROADCAST', 'UDP_IP', fallback="192.168.1.255")
_DESCRIPTION_IO = "\tSENDER - RECEIVER vía UDP. Broadcast IP: {}, PORT: {}"


def get_encryption_key(key_file=None):
    """
    Encryption key for symmetric encryption. URL-safe base64-encoded 32-byte key

    * Get local key, or exec wizard for making one.

    :param: key_file: :str: path of the file with the encryption key
    :return: :bytes: encryption_key
    """

    if key_file is None:
        key_file = os.path.join(
            DATA_PATH,
Esempio n. 11
0
"""
from enerpi.base import CONFIG, log, CONFIG_FILENAME
import datetime as dt
# dateutil included in python-dateutil
# noinspection PyPackageRequirements
from dateutil.parser import parse


# PINOUT RGB_LED
WITH_RGBLED = CONFIG.getboolean('RGBLED', 'WITH_RGBLED', fallback=False)
PIN_R = CONFIG.getint('RGBLED', 'PIN_R', fallback=19)
PIN_G = CONFIG.getint('RGBLED', 'PIN_G', fallback=20)
PIN_B = CONFIG.getint('RGBLED', 'PIN_B', fallback=16)

# Horario de funcionamiento del RGB LED
LED_TIME_ON = CONFIG.get('RGBLED', 'TIME_ON', fallback=None)
LED_TIME_OFF = CONFIG.get('RGBLED', 'TIME_OFF', fallback=None)
if LED_TIME_ON is not None:
    LED_TIME_ON = parse(LED_TIME_ON)
if LED_TIME_OFF is not None:
    LED_TIME_OFF = parse(LED_TIME_OFF)


def _use_led():
    if LED_TIME_ON and LED_TIME_OFF:
        if LED_TIME_ON.time() < dt.datetime.now().time() < LED_TIME_OFF.time():
            return True
        return False
    return True

Esempio n. 12
0
        'show_switch_comments': True,
    },
    'sensors': {
        'order': 1,
        'filename': 'sensors_enerpi.json',
        'text_button':
        '<i class="fa fa-wrench" aria-hidden="true"></i> SENSORS',
        'show_switch_comments': False,
    },
    'encryption_key': {
        'order':
        2,
        'filename':
        os.path.join(
            DATA_PATH,
            CONFIG.get('BROADCAST', 'KEY_FILE', fallback='.secret_key')),
        'text_button':
        '<i class="fa fa-user-secret" aria-hidden="true"></i> Secret Key',
        'show_switch_comments':
        False,
    },
}

TITLE_EDIT_CRYPTOKEY = 'Encryption KEY'
SUBTITLE_EDIT_CRYPTOKEY = 'KEY_FILE'
TITLE_EDIT_JS_SENSORS = 'SENSORS'
SUBTITLE_EDIT_JS_SENSORS = 'SENSORS'

OPTIONAL_PARAMS = ['PUSHBULLET_TOKEN', 'EMAIL_RECIPIENT']

Esempio n. 13
0
from flask_autodoc import Autodoc
from flask_mail import Mail
from werkzeug.contrib.fixers import ProxyFix
from werkzeug.routing import Rule
import jinja2
import os
# noinspection PyUnresolvedReferences
from enerpi import __version__
from enerpi.base import (CONFIG, DATA_PATH, check_resource_files,
                         GMAIL_ACCOUNT, GMAIL_APP_PASSWORD)
from enerpi.api import get_encryption_key


basedir = os.path.abspath(os.path.dirname(__file__))
STATIC_PATH = os.path.join(
    DATA_PATH, CONFIG.get('ENERPI_WEBSERVER', 'STATIC_PATH', fallback='WWW'))
LOGGING_LEVEL_SERVER = CONFIG.get(
    'ENERPI_WEBSERVER', 'LOGGING_LEVEL_WEB', fallback='DEBUG')
SERVER_FILE_LOGGING = os.path.join(
    STATIC_PATH, CONFIG.get(
        'ENERPI_WEBSERVER', 'FILE_LOGGING_WEB', fallback='enerpiweb.log'))
PREFIX_WEB = CONFIG.get('ENERPI_WEBSERVER', 'PREFIX_WEB', fallback='/enerpi')
BASECOLOR = '#{}'.format(
    CONFIG.get('ENERPI_WEBSERVER', 'BASECOLOR_HEX', fallback='0CBB43'))
check_resource_files(
    STATIC_PATH, os.path.join(basedir, 'static'), verbose=False)

# WITH_WEB = CONFIG.getboolean('ENERPI_WEBSERVER', 'WITH_WEBSERVER',
# fallback=True)
WITH_ML_SUBSYSTEM = CONFIG.getboolean('ENERPI_WEBSERVER', 'WITH_ML',
                                      fallback=False)
Esempio n. 14
0
ENERPI_CONFIG_FILES = {
    'config': {
        'order': 0,
        'filename': 'config_enerpi.ini',
        'text_button': '<i class="fa fa-check-square-o" aria-hidden="true"></i> ENERPI config',
        'show_switch_comments': True,
    },
    'sensors': {
        'order': 1,
        'filename': 'sensors_enerpi.json',
        'text_button': '<i class="fa fa-wrench" aria-hidden="true"></i> SENSORS',
        'show_switch_comments': False,
    },
    'encryption_key': {
        'order': 2,
        'filename': os.path.join(DATA_PATH, CONFIG.get('BROADCAST', 'KEY_FILE', fallback='.secret_key')),
        'text_button': '<i class="fa fa-user-secret" aria-hidden="true"></i> Secret Key',
        'show_switch_comments': False,
    },
}

TITLE_EDIT_CRYPTOKEY = 'Encryption KEY'
SUBTITLE_EDIT_CRYPTOKEY = 'KEY_FILE'
TITLE_EDIT_JS_SENSORS = 'SENSORS'
SUBTITLE_EDIT_JS_SENSORS = 'SENSORS'

OPTIONAL_PARAMS = ['PUSHBULLET_TOKEN', 'EMAIL_RECIPIENT']


def _web_edit_enerpi_config_ini(lines_ini_file):
    """
Esempio n. 15
0
- Install configuration & CRON task for web resources generation
- Uninstall CRON task
- Run Flask server

"""
import argparse
import os
import sys
from enerpi.base import BASE_PATH, DATA_PATH, CONFIG, log, check_resource_files, NGINX_CONFIG_FILE, UWSGI_CONFIG_FILE
from enerpi.prettyprinting import print_secc, print_cyan, print_red, print_magenta


FLASK_WEBSERVER_PORT = CONFIG.getint('ENERPI_WEBSERVER', 'FLASK_WEBSERVER_PORT', fallback=7777)
PERIOD_MINUTES_RSC_GEN = CONFIG.getint('ENERPI_WEBSERVER', 'RSC_GEN_EVERY_MINUTES', fallback=15)
USER_SERVER = CONFIG.get('ENERPI_WEBSERVER', 'USER_SERVER', fallback='www-data')
basedir = os.path.abspath(os.path.dirname(__file__))


def make_cron_command_task_periodic_rscgen():
    """
    CRON task for generate web resources with enerpiplot.mule_rscgen.py
    Example command:
    */15 * * * * sudo -u www-data /home/pi/PYTHON/py35/bin/python
        /home/pi/PYTHON/py35/lib/python3.5/site-packages/enerpiweb/mule_rscgen.py -o

    :return: :str: cron_command
    """
    # cmd_server = '*/{period} * * * * ...'
    cmd_server = 'sudo -u {user_server} {python_pathbin}/python3 {path_enerpiplot}/mule_rscgen.py -o'
    local_params = dict(path_enerpiplot=os.path.abspath(os.path.join(BASE_PATH, '..', 'enerpiplot')),
Esempio n. 16
0
def enerpi_main_cli(test_mode=False):
    """
    Uso de ENERPI desde CLI

    enerpi -h para mostrar las diferentes opciones

    """
    # CLI Arguments
    args = _enerpi_arguments()
    verbose = not args.silent

    if args.version:
        return __version__

    # CONTROL LOGIC
    # Shows RPI Temps
    timer_temps = show_pi_temperature(args.temps, 3, args.timeout)

    if args.install or args.uninstall:
        from enerpi.config.crontasks import set_command_on_reboot, clear_cron_commands
        # INSTALL / UNINSTALL CRON TASKS & KEY
        cmd_logger = make_cron_command_task_daemon()
        if args.install:
            # Logging configuration
            set_logging_conf(FILE_LOGGING, LOGGING_LEVEL, True)

            log('** Installing CRON task for start logger at reboot:\n"{}"'.format(cmd_logger), 'ok', True, False)
            set_command_on_reboot(cmd_logger, verbose=verbose)
            try:
                os.chmod(DATA_PATH, 0o777)
                [os.chmod(os.path.join(base, f), 0o777)
                 for base, dirs, files in os.walk(DATA_PATH) for f in files + dirs]
            except PermissionError:
                log("Can't set 777 permissions on {0}/* files...\nDo it manually, please: 'sudo chmod 777 -R {0}'"
                    .format(DATA_PATH), 'warning', True, False)
        else:
            log('** Deleting CRON task for start logger at reboot:\n"{}"'.format(cmd_logger), 'warn', True, False)
            clear_cron_commands([cmd_logger], verbose=verbose)
    elif (args.enerpi or args.info or args.backup or args.reprocess or args.config or args.raw or
            args.last or args.clearlog or args.filter or args.plot or args.plot_tiles):
        # Init CLI
        # import matplotlib
        # matplotlib.use('Agg')
        import matplotlib.pyplot as plt
        import pandas as pd
        pd.set_option('display.width', 200)

        # Logging configuration
        set_logging_conf(FILE_LOGGING, LOGGING_LEVEL, True)

        # Shows INI config & SENSORS
        if args.config:
            import json

            log('ENERPI Configuration (from INI file in "{}"):'
                .format(os.path.join(DATA_PATH, CONFIG_FILENAME)), 'ok', True, False)
            for s in CONFIG.sections():
                log('* Section {}:'.format(s), 'info', True, False)
                for opt in CONFIG.options(s):
                    log('{:27} -->\t{}'.format(opt.upper(), CONFIG.get(s, opt)), 'debug', True, False)
            log('*' * 80 + '\n', 'ok', True, False)
            log('\nENERPI SENSORS Config (from JSON file in "{}"):'
                .format(os.path.join(DATA_PATH, SENSORS_CONFIG_JSON_FILENAME)), 'ok', True, False)
            json_content = json.loads(open(os.path.join(DATA_PATH, SENSORS_CONFIG_JSON_FILENAME), 'r').read())
            log('\n'.join(['{}'.format(s) for s in json_content]), 'magenta', True, False)
            log('--> {}\n\n'.format(SENSORS), 'ok', True, False)
        # Delete LOG File
        if args.clearlog:
            from enerpi.database import delete_log_file

            delete_log_file(FILE_LOGGING, verbose=verbose)
        # Data Store Config
        _existe_st, path_st = _check_store_relpath(args.store)

        # Starts ENERPI Logger
        if args.enerpi:
            from enerpi.enerpimeter import enerpi_logger

            # Demo logger
            if args.demo:
                set_logging_conf(FILE_LOGGING + '_demo.log', LOGGING_LEVEL, True)
                path_st = os.path.join(DATA_PATH, 'debug_buffer_disk.h5')
            enerpi_logger(is_demo=args.demo, verbose=verbose, path_st=path_st, delta_sampling=args.delta,
                          roll_time=args.window, sampling_ms=args.ts, timeout=args.timeout)
        elif args.backup:
            from enerpi.database import init_catalog
            # Export data to CSV:
            catalog = init_catalog(sensors=SENSORS, raw_file=path_st, check_integrity=False,
                                   verbose=verbose, test_mode=test_mode)
            export_ok = catalog.export_chunk(args.backup)
            log('EXPORT OK? {}'.format(export_ok), 'ok' if export_ok else 'error', True, False)
        elif args.reprocess:
            from enerpi.database import init_catalog
            # Re-process all data in catalog
            catalog = init_catalog(sensors=SENSORS, raw_file=path_st, check_integrity=False,
                                   verbose=verbose, test_mode=test_mode)
            repro_ok = catalog.reprocess_all_data()
            log('REPROCESS OK? {}'.format(repro_ok), 'ok' if repro_ok else 'error', verbose, verbose)
        # TODO revisar config X11 + ssh -X para plot en display local
        elif args.raw:
            from enerpi.enerpimeter import enerpi_raw_data

            # Raw mode
            delta_secs = args.raw
            raw_data = enerpi_raw_data(path_st.replace('.h5', '_raw_sample.h5'), delta_secs=delta_secs,
                                       use_dummy_sensors=args.demo,
                                       roll_time=args.window, sampling_ms=args.ts, verbose=verbose)
            t0, tf = raw_data.index[0], raw_data.index[-1]
            log('Showing RAW DATA for {} seconds ({} samples, {:.2f} sps)\n** Real data: from {} to {} --> {:.2f} sps'
                .format(delta_secs, len(raw_data), len(raw_data) / delta_secs,
                        t0, tf, len(raw_data) / (tf-t0).total_seconds()), 'info', verbose, False)
            raw_data.plot(lw=.5, figsize=(16, 10))
            plt.show()
        # Shows database info
        elif args.info or args.filter or args.plot or args.plot_tiles:
            from enerpi.database import init_catalog, show_info_data

            catalog = init_catalog(sensors=SENSORS, raw_file=path_st, check_integrity=False,
                                   verbose=verbose, test_mode=test_mode)
            if args.plot_tiles:
                from enerpiplot.enerplot import gen_svg_tiles

                ok = gen_svg_tiles(IMG_TILES_BASEPATH, catalog, color=COLOR_TILES if not test_mode else (1, 0, 0))
                if ok:
                    log('SVG Tiles generated!', 'ok', verbose, True)
                else:
                    log('No generation of SVG Tiles!', 'error', verbose, True)
            else:
                data, consumption = _extract_time_slice_from_args(args.filter, args.info, catalog)

                if (args.info or args.filter) and data is not None and not data.empty:
                    show_info_data(data, consumption)
                if (args.plot and (data is not None) and not data.empty and (consumption is not None) and
                        not consumption.empty):
                    from enerpiplot.enerplot import plot_power_consumption_hourly

                    rs_data, rm_data, path_saveimg, show = _extract_plot_params_from_args(args.plot, args.plot_options)
                    mean_sensor_data = data[SENSORS.columns_sensors_mean] if SENSORS.columns_sensors_mean else None
                    log('Generate PLOT with RESAMPLE={}, ROLLING={}, show={}, path_save="{}"'
                        .format(rs_data, rm_data, show, path_saveimg), 'info', verbose, False)
                    img_name = plot_power_consumption_hourly(data[SENSORS.columns_sensors_rms],
                                                             consumption.kWh, data_mean_s=mean_sensor_data,
                                                             rs_data=rs_data, rm_data=rm_data,
                                                             show=show, path_saveimg=path_saveimg)
                    if img_name is not None:
                        log('IMAGE saved in "{}"'.format(img_name), 'ok', verbose, False)
        # Shows database info
        else:  # Shows last 10 entries
            from enerpi.database import get_ts_last_save

            last = get_ts_last_save(path_st, get_last_sample=True, verbose=verbose, n=10)
            log('Showing last 10 entries in {}:\n{}'.format(path_st, last), 'info', verbose, False)
    # Shows & extract info from LOG File
    elif args.log:
        from enerpi.database import extract_log_file

        data_log = extract_log_file(FILE_LOGGING, extract_temps=True, verbose=verbose)
        try:
            df_temps = data_log[data_log.temp.notnull()].drop(['tipo', 'msg', 'debug_send'], axis=1).dropna(axis=1)
            if len(set(df_temps['exec'])) == 1:
                df_temps = df_temps.drop(['exec'], axis=1)
            path_csv = os.path.join(DATA_PATH, 'debug_rpitemps.csv')
            if not df_temps.empty:
                df_temps.to_csv(path_csv)
                print('*** Saved temperature data extracted from LOG in {}'.format(path_csv))
        except AttributeError:
            print('No se encuentran datos de Tª de RPI en el LOG')
    # Demo sender
    elif args.demo:
        from enerpi.enerpimeter import enerpi_logger

        set_logging_conf(FILE_LOGGING + '_demo.log', LOGGING_LEVEL, True)
        path_st = os.path.join(DATA_PATH, 'debug_buffer_disk.h5')
        enerpi_logger(is_demo=True, verbose=verbose, path_st=path_st, delta_sampling=args.delta,
                      roll_time=args.window, sampling_ms=args.ts, timeout=args.timeout)
    # Receiver
    else:  # elif args.receive:
        from enerpi.enerpimeter import receiver

        log('{}\n   {}'.format(PRETTY_NAME, DESCRIPTION), 'ok', verbose, False)
        receiver(verbose=verbose, timeout=args.timeout, port=args.port)
    if timer_temps is not None:
        log('Stopping RPI TEMPS sensing...', 'debug', True)
        timer_temps.cancel()
    log('Exiting from ENERPI CLI...', 'debug', True)
    if not test_mode:
        sys.exit(0)
Esempio n. 17
0
ENERPI - CLI methods & argument parser

"""
import datetime as dt
import os
import re
import sys
from enerpi import PRETTY_NAME, DESCRIPTION, __version__
from enerpi.base import (IMG_TILES_BASEPATH, DATA_PATH, CONFIG, SENSORS, CONFIG_FILENAME, SENSORS_CONFIG_JSON_FILENAME,
                         FILE_LOGGING, LOGGING_LEVEL, set_logging_conf, log, show_pi_temperature,
                         DEFAULT_IMG_MASK, COLOR_TILES)


# Config:
UDP_PORT = CONFIG.getint('BROADCAST', 'UDP_PORT', fallback=57775)
HDF_STORE = CONFIG.get('ENERPI_DATA', 'HDF_STORE')


def _enerpi_arguments():
    """
    CLI Parser
    """
    import argparse

    p = argparse.ArgumentParser(description="\033[1m\033[5m\033[32m{}\033[0m\n{}\n\n".format(PRETTY_NAME, DESCRIPTION),
                                epilog='\033[34m\n*** By default, ENERPI starts as receiver (-r) ***\n' +
                                       '\033[0m', formatter_class=argparse.RawTextHelpFormatter)
    g_m = p.add_argument_group(title='☆  \033[1m\033[4mENERPI Working Mode\033[24m',
                               description='→  Choose working mode between RECEIVER / SENDER')
    g_m.add_argument('-e', '--enerpi', action='store_true', help='⚡  SET ENERPI LOGGER & BROADCAST MODE')
    g_m.add_argument('-r', '--receive', action='store_true', help='⚡  SET Broadcast Receiver mode (by default)')
Esempio n. 18
0
"""
from enerpi.base import CONFIG, log, CONFIG_FILENAME
import datetime as dt
# dateutil included in python-dateutil
# noinspection PyPackageRequirements
from dateutil.parser import parse

# PINOUT RGB_LED
WITH_RGBLED = CONFIG.getboolean('RGBLED', 'WITH_RGBLED', fallback=False)
PIN_R = CONFIG.getint('RGBLED', 'PIN_R', fallback=19)
PIN_G = CONFIG.getint('RGBLED', 'PIN_G', fallback=20)
PIN_B = CONFIG.getint('RGBLED', 'PIN_B', fallback=16)

# Horario de funcionamiento del RGB LED
LED_TIME_ON = CONFIG.get('RGBLED', 'TIME_ON', fallback=None)
LED_TIME_OFF = CONFIG.get('RGBLED', 'TIME_OFF', fallback=None)
if LED_TIME_ON is not None:
    LED_TIME_ON = parse(LED_TIME_ON)
if LED_TIME_OFF is not None:
    LED_TIME_OFF = parse(LED_TIME_OFF)


def _use_led():
    if LED_TIME_ON and LED_TIME_OFF:
        if LED_TIME_ON.time() < dt.datetime.now().time() < LED_TIME_OFF.time():
            return True
        return False
    return True

Esempio n. 19
0
import pandas as pd
from threading import Timer
from time import sleep, time
from enerpi.base import (CONFIG, SENSORS, DATA_PATH, TimerExiter, show_pi_temperature,
                         set_logging_conf, log, FILE_LOGGING, LOGGING_LEVEL)
from enerpi.database import init_catalog, save_raw_data, HDF_STORE_PATH
from enerpi.pisampler import enerpi_sampler_rms, enerpi_raw_sampler, msg_to_dict, tuple_to_dict_json
from enerpi.iobroadcast import get_codec, broadcast_msg, receiver_msg_generator
from enerpi.ledrgb import get_rgbled, led_info, led_alarm, blink_color
from enerpi.notifier import push_enerpi_error


# Disk data store
N_SAMPLES_BUFFER_DISK = CONFIG.getint('ENERPI_DATA', 'N_SAMPLES_BUFFER_DISK', fallback=60)
STORE_PERIODIC_CATALOG_SEC = CONFIG.getint('ENERPI_DATA', 'STORE_PERIODIC_CATALOG_SEC', fallback=3600)
INIT_LOG_MARK = CONFIG.get('ENERPI_SAMPLER', 'INIT_LOG_MARK', fallback='INIT')

# Variable global para controlar el estado de notificaciones vía RGB LED
LED_STATE = 0

PALETA = dict(off=(0., (0., 0., 1.)),
              standby=(250., (0., 1., 0.)),
              medium=(750., (1., .5, 0.)),
              high=(3500., (1., 0., 0.)),
              max=(4500., (1., 0., 1.)))

# Decay control
# (# of samples/s dropping a lot sometimes
#       --> y = -a * x**2. x(9:32)=1300, x(9:37)=1190, x(9:48)=995)
MIN_N_SAMPLES_DELTA_FRACTION = .5
MIN_N_SAMPLES_MAX_CONSIDERED = 900
Esempio n. 20
0
# -*- coding: utf-8 -*-
"""
ENERPI - Broadcast receiver & emitter

"""
from cryptography.fernet import Fernet, InvalidToken
from binascii import Error
import os
import socket
import sys
from time import time
from enerpi.base import DATA_PATH, CONFIG, log


# LAN broadcasting
_UDP_IP = CONFIG.get('BROADCAST', 'UDP_IP', fallback="192.168.1.255")
_DESCRIPTION_IO = "\tSENDER - RECEIVER vía UDP. Broadcast IP: {}, PORT: {}"


def get_encryption_key(key_file=None):
    """
    Encryption key for symmetric encryption. URL-safe base64-encoded 32-byte key

    * Get local key, or exec wizard for making one.

    :param: key_file: :str: path of the file with the encryption key
    :return: :bytes: encryption_key
    """

    if key_file is None:
        key_file = os.path.join(DATA_PATH, CONFIG.get('BROADCAST', 'KEY_FILE', fallback='.secret_key'))
Esempio n. 21
0
"""
import argparse
import os
import sys
from enerpi.base import BASE_PATH, DATA_PATH, CONFIG, log, check_resource_files, NGINX_CONFIG_FILE, UWSGI_CONFIG_FILE
from enerpi.prettyprinting import print_secc, print_cyan, print_red, print_magenta

FLASK_WEBSERVER_PORT = CONFIG.getint('ENERPI_WEBSERVER',
                                     'FLASK_WEBSERVER_PORT',
                                     fallback=7777)
PERIOD_MINUTES_RSC_GEN = CONFIG.getint('ENERPI_WEBSERVER',
                                       'RSC_GEN_EVERY_MINUTES',
                                       fallback=15)
USER_SERVER = CONFIG.get('ENERPI_WEBSERVER',
                         'USER_SERVER',
                         fallback='www-data')
basedir = os.path.abspath(os.path.dirname(__file__))


def make_cron_command_task_periodic_rscgen():
    """
    CRON task for generate web resources with enerpiplot.mule_rscgen.py
    Example command:
    */15 * * * * sudo -u www-data /home/pi/PYTHON/py35/bin/python
        /home/pi/PYTHON/py35/lib/python3.5/site-packages/enerpiweb/mule_rscgen.py -o

    :return: :str: cron_command
    """
    # cmd_server = '*/{period} * * * * ...'
    cmd_server = 'sudo -u {user_server} {python_pathbin}/python3 {path_enerpiplot}/mule_rscgen.py -o'
Esempio n. 22
0
from flask import Flask
from flask_autodoc import Autodoc
from flask_mail import Mail
from werkzeug.contrib.fixers import ProxyFix
from werkzeug.routing import Rule
import jinja2
import os
# noinspection PyUnresolvedReferences
from enerpi import __version__
from enerpi.base import (CONFIG, DATA_PATH, check_resource_files,
                         GMAIL_ACCOUNT, GMAIL_APP_PASSWORD)
from enerpi.api import get_encryption_key

basedir = os.path.abspath(os.path.dirname(__file__))
STATIC_PATH = os.path.join(
    DATA_PATH, CONFIG.get('ENERPI_WEBSERVER', 'STATIC_PATH', fallback='WWW'))
LOGGING_LEVEL_SERVER = CONFIG.get('ENERPI_WEBSERVER',
                                  'LOGGING_LEVEL_WEB',
                                  fallback='DEBUG')
SERVER_FILE_LOGGING = os.path.join(
    STATIC_PATH,
    CONFIG.get('ENERPI_WEBSERVER',
               'FILE_LOGGING_WEB',
               fallback='enerpiweb.log'))
PREFIX_WEB = CONFIG.get('ENERPI_WEBSERVER', 'PREFIX_WEB', fallback='/enerpi')
BASECOLOR = '#{}'.format(
    CONFIG.get('ENERPI_WEBSERVER', 'BASECOLOR_HEX', fallback='0CBB43'))
check_resource_files(STATIC_PATH,
                     os.path.join(basedir, 'static'),
                     verbose=False)