text: import datetime as dt
  import time
  from copy import deepcopy
  from operator import itemgetter
  #from .polylogger import LOGGER
  import logging
  
  NLOGGER = logging.getLogger(__name__)
  NLOGGER.setLevel("ERROR")
  
  class Node(object):
      """
      Node Class for individual devices.
      """
  
      def __init__(self, poly, primary, address, name):
          try:
              self.poly = poly
              self.primary = primary # parent address
              self.address = address
              self.name = name
              self.polyConfig = None
              self.drivers = deepcopy(self.drivers)
              self.isPrimary = None
              self.config = None
              self.timeAdded = dt.datetime.now()
              self.enabled = None
              self.added = None
              self.private = None
          except (KeyError) as err:
              NLOGGER.error('Error Creating node: {}'.format(err), exc_info=True)
  
      def __setitem__(self, name, value):
          self.__dict__[name] = value
  
      def _convertDrivers(self, drivers):
          return deepcopy(drivers)
          """
          if isinstance(drivers, list):
              newFormat = {}
              for driver in drivers:
                  newFormat[driver['driver']] = {}
                  newFormat[driver['driver']]['value'] = driver['value']
                  newFormat[driver['driver']]['uom'] = driver['uom']
              return newFormat
          else:
              return deepcopy(drivers)
          """
  
      def updateDrivers(self, drivers):
          self.drivers = deepcopy(drivers)
  
      def getDriver(self, driver):
          """
          Get the driver value
          """
          for dv in self.drivers:
              NLOGGER.debug('{} - {} :: getting dv {}'.format(dv['driver'], dv['value'], driver))
              if dv['driver'] == driver:
                  return dv['value']
  
          return None
  
      def setDriver(self, driver, value, report=True, force=False, uom=None):
          """ Update the driver's value and when report=True, update the ISY """
          changed = False
  
          drv = next((item for (item,d) in enumerate(self.drivers) if d['driver'] == driver), None)
          if drv == None:
              NLOGGER.error('setDriver: Invalid driver: {}'.format(driver))
              return
  
          if uom != None and self.drivers[drv]['uom'] != uom:
              self.drivers[drv]['uom'] = uom
              changed = True
  
          if self.drivers[drv]['value'] != value:
              self.drivers[drv]['value'] = value
              changed = True
  
          if report and (changed or force):
              NLOGGER.debug('Reporting set {} to {} to Polyglot'.format(driver, value))
              self.reportDriver(driver, force)
          else:
              NLOGGER.debug('No change in {}\'s value'.format(driver))
  
      def reportDriver(self, driver, force):
          """ Send existing driver value to ISY """
          drv = next((item for (item,d) in enumerate(self.drivers) if d['driver'] == driver), None)
          if drv is not None:
              message = {
                  'set': [{
                      'address': self.address,
                      'driver': self.drivers[drv]['driver'],
                      'value': str(self.drivers[drv]['value']),
                      'uom': self.drivers[drv]['uom']
                  }]
              }
              NLOGGER.debug('Updating value to {}'.format(self.drivers[drv]['value']))
              self.poly.send(message, 'status')
  
      def reportDrivers(self):
          NLOGGER.info('Updating All Drivers to ISY for {}({})'.format(
              self.name, self.address))
          #self.updateDrivers(self.drivers)
          message = {'set': []}
          for driver in self.drivers:
              message['set'].append(
                  {
                      'address': self.address,
                      'driver': driver['driver'],
                      'value': driver['value'],
                      'uom': driver['uom']
                  })
          self.poly.send(message, 'status')
  
      def query(self):
          self.reportDrivers()
  
      def status(self):
          self.reportDrivers()
  
      def reportCmd(self, command, value=None, uom=None):
          message = {
              'command': [{
                  'address': self.address,
                  'cmd': command
              }]
          }
          if value is not None and uom is not None:
              message['command'][0]['value'] = str(value)
              message['command'][0]['uom'] = uom
          self.poly.send(message, 'command')
  
      def runCmd(self, command):
          """ Execute the function attached to the command """
          if 'cmd' in command:
              if command['cmd'] in self.commands:
                  fun = self.commands[command['cmd']]
                  fun(self, command)
              else:
                  NLOGGER.error('command {} not defined'.format(command['cmd']))
          elif 'success' in command:
              if not command['success']:
                  NLOGGER.error('Command message failed: {}'.format(command))
  
          else:
              NLOGGER.error('Invalid command message: {}'.format(command))
  
  
      def start(self):
          pass
  
      def toJSON(self):
          NLOGGER.debug(json.dumps(self.__dict__))
  
      def __rep__(self):
          return self.toJSON()
  
      id = ''
      commands = {}
      drivers = []
      sends = {}
      hint = [0, 0, 0, 0]
      private = None
  
  