# Path: myDevices/utils/config.py
# class Config:
#     def __init__(self, path):
#         self.mutex = RLock()
#         self.path = path
#         self.config = RawConfigParser()
#         self.config.optionxform = str
#         try:
#             with open(path) as fp:
#                 self.config.read_file(fp)
#         except:
#             pass
#             
#     def set(self, section, key, value):
#         with self.mutex:
#             try:
#                 self.config.set(section, key, value)
#             except NoSectionError:
#                 self.config.add_section(section)
#                 self.config.set(section, key, value)
#         self.save()
# 
#     def get(self, section, key, fallback=_UNSET):
#         return self.config.get(section, key, fallback=fallback)
# 
#     def getInt(self, section, key, fallback=_UNSET):
#         return self.config.getint(section, key, fallback=fallback)
#     
#     def remove(self, section, key):
#         with self.mutex:
#             result = self.config.remove_option(section, key)       
#         self.save()
# 
#     def save(self):
#         with self.mutex:
#             with open(self.path, 'w') as configfile:
#                 self.config.write(configfile)
# 
#     def sections(self):
#         return self.config.sections()
# 
# Path: myDevices/utils/logger.py
# def debug(message):
#     outerFrame = getouterframes(currentframe())[1][0]
#     (args, _, _, values) = getargvalues(outerFrame)
#     argsValue = ''
#     
#     for i in args:
#         if i is 'self':
#             continue
#         argsValue += "(%s=%s)" % (i, str(values[i]))
#     
#     stack = extract_stack()
#     (filename, line, procname, text) = stack[-2]
#     LOGGER.debug(str(filename) + ' ' + str(procname) + str(argsValue) + ':' + str(line) + '> '  + str(message))
# 
# def error(message, *args, **kwargs):
#     if checkFlood(message):
#         return
#     LOGGER.error(message, *args, **kwargs)
# 
# def exception(message):
#     if checkFlood(message):
#         return
#     LOGGER.exception(message)
# 
# def info(message):
#     # if checkFlood(message):
#     #     return
#     LOGGER.info(message)
# 
# Path: myDevices/utils/singleton.py
# class Singleton(_Singleton('SingletonMeta', (object,), {})): pass
# 
# Path: myDevices/utils/subprocess.py
# def executeCommand(command, increaseMemoryLimit=False, disablePipe=False):
#     """Execute a specified command, increasing the processes memory limits if specified"""
#     debug('executeCommand: ' +  command)
#     output = ''
#     returncode = 1
#     try:
#         preexec = None
#         pipe = PIPE
#         if increaseMemoryLimit:
#             preexec = setMemoryLimits
#         if disablePipe:
#             debug('Disable pipe to prevent child exiting when parent exits')
#             pipe = DEVNULL
#         process = Popen(command, stdout=pipe, stderr=pipe, shell=True, preexec_fn=preexec)
#         (stdout_data, stderr_data) = process.communicate()
#         returncode = process.wait()
#         returncode = process.returncode
#         # debug('executeCommand: stdout_data {}, stderr_data {}'.format(stdout_data, stderr_data))
#         if stdout_data:
#             output = stdout_data.decode('utf-8')
#             stdout_data = None
#     except:
#         exception('executeCommand failed: ' + command)
#     return (output, returncode)


import fnmatch
import importlib
import json
import os
import sys
import myDevices.cloud.cayennemqtt as cayennemqtt
from configparser import NoOptionError
from myDevices.utils.config import Config
from myDevices.utils.logger import debug, error, exception, info
from myDevices.utils.singleton import Singleton
from myDevices.utils.subprocess import executeCommand
            return key in self.plugins.keys()
        except:
            return False

    def write_value(self, plugin, channel, value):
        """Write a value to a plugin actuator.
        
        Returns: True if value written, False if it was not"""
        actuator = plugin + ':' + channel
        info('Write value {} to {}'.format(value, actuator))
        if actuator in self.plugins.keys():
            try:
                write_function = getattr(self.plugins[actuator]['instance'], self.plugins[actuator]['write'])
                write_args = self.get_args(self.plugins[actuator], 'write_args')
                write_function(float(value), **write_args)
            except KeyError as e:
                error('Error writing value, missing key: {}'.format(e))
                return False    
            except Exception as e:
                error('Error writing value: {}'.format(e))
                return False
        else:
            return False
        return True

    def disable(self, plugin_id):
        """Disable the specified plugin."""
        disabled = False
        try:
            plugin = self.plugins[plugin_id]

# Path: myDevices/utils/config.py
# class Config:
#     def __init__(self, path):
#         self.mutex = RLock()
#         self.path = path
#         self.config = RawConfigParser()
#         self.config.optionxform = str
#         try:
#             with open(path) as fp:
#                 self.config.read_file(fp)
#         except:
#             pass
#             
#     def set(self, section, key, value):
#         with self.mutex:
#             try:
#                 self.config.set(section, key, value)
#             except NoSectionError:
#                 self.config.add_section(section)
#                 self.config.set(section, key, value)
#         self.save()
# 
#     def get(self, section, key, fallback=_UNSET):
#         return self.config.get(section, key, fallback=fallback)
# 
#     def getInt(self, section, key, fallback=_UNSET):
#         return self.config.getint(section, key, fallback=fallback)
#     
#     def remove(self, section, key):
#         with self.mutex:
#             result = self.config.remove_option(section, key)       
#         self.save()
# 
#     def save(self):
#         with self.mutex:
#             with open(self.path, 'w') as configfile:
#                 self.config.write(configfile)
# 
#     def sections(self):
#         return self.config.sections()
# 
# Path: myDevices/utils/logger.py
# def debug(message):
#     outerFrame = getouterframes(currentframe())[1][0]
#     (args, _, _, values) = getargvalues(outerFrame)
#     argsValue = ''
#     
#     for i in args:
#         if i is 'self':
#             continue
#         argsValue += "(%s=%s)" % (i, str(values[i]))
#     
#     stack = extract_stack()
#     (filename, line, procname, text) = stack[-2]
#     LOGGER.debug(str(filename) + ' ' + str(procname) + str(argsValue) + ':' + str(line) + '> '  + str(message))
# 
# def error(message, *args, **kwargs):
#     if checkFlood(message):
#         return
#     LOGGER.error(message, *args, **kwargs)
# 
# def exception(message):
#     if checkFlood(message):
#         return
#     LOGGER.exception(message)
# 
# def info(message):
#     # if checkFlood(message):
#     #     return
#     LOGGER.info(message)
# 
# Path: myDevices/utils/singleton.py
# class Singleton(_Singleton('SingletonMeta', (object,), {})): pass
# 
# Path: myDevices/utils/subprocess.py
# def executeCommand(command, increaseMemoryLimit=False, disablePipe=False):
#     """Execute a specified command, increasing the processes memory limits if specified"""
#     debug('executeCommand: ' +  command)
#     output = ''
#     returncode = 1
#     try:
#         preexec = None
#         pipe = PIPE
#         if increaseMemoryLimit:
#             preexec = setMemoryLimits
#         if disablePipe:
#             debug('Disable pipe to prevent child exiting when parent exits')
#             pipe = DEVNULL
#         process = Popen(command, stdout=pipe, stderr=pipe, shell=True, preexec_fn=preexec)
#         (stdout_data, stderr_data) = process.communicate()
#         returncode = process.wait()
#         returncode = process.returncode
#         # debug('executeCommand: stdout_data {}, stderr_data {}'.format(stdout_data, stderr_data))
#         if stdout_data:
#             output = stdout_data.decode('utf-8')
#             stdout_data = None
#     except:
#         exception('executeCommand failed: ' + command)
#     return (output, returncode)


# Path: myDevices/plugins/manager.py
import fnmatch
import importlib
import json
import os
import sys
import myDevices.cloud.cayennemqtt as cayennemqtt
from configparser import NoOptionError
from myDevices.utils.config import Config
from myDevices.utils.logger import debug, error, exception, info
from myDevices.utils.singleton import Singleton
from myDevices.utils.subprocess import executeCommand

            return key in self.plugins.keys()
        except:
            return False

    def write_value(self, plugin, channel, value):
        """Write a value to a plugin actuator.
        
        Returns: True if value written, False if it was not"""
        actuator = plugin + ':' + channel
        info('Write value {} to {}'.format(value, actuator))
        if actuator in self.plugins.keys():
            try:
                write_function = getattr(self.plugins[actuator]['instance'], self.plugins[actuator]['write'])
                write_args = self.get_args(self.plugins[actuator], 'write_args')
                write_function(float(value), **write_args)
            except KeyError as e:
                error('Error writing value, missing key: {}'.format(e))
                return False    
            except Exception as e:
                error('Error writing value: {}'.format(e))
                return False
        else:
            return False
        return True

    def disable(self, plugin_id):
        """Disable the specified plugin."""
        disabled = False
        try:
            plugin = self.plugins[plugin_id]

            output, result = executeCommand('sudo python3 -m myDevices.plugins.disable "{}" "{}"'.format(plugin['filename'], plugin['section']))