# Modbus Simulator Example

    #!/usr/bin/env python
    '''
    An example of creating a fully implemented modbus server
    with read/write data as well as user configurable base data
    '''

    import pickle
    from optparse import OptionParser
    from twisted.internet import reactor

    from pymodbus.server.async import StartTcpServer
    from pymodbus.datastore import ModbusServerContext,ModbusSlaveContext

    #--------------------------------------------------------------------------#
    # Logging
    #--------------------------------------------------------------------------#
    import logging
    logging.basicConfig()

    server_log   = logging.getLogger("pymodbus.server")
    protocol_log = logging.getLogger("pymodbus.protocol")

    #---------------------------------------------------------------------------#
    # Extra Global Functions
    #---------------------------------------------------------------------------#
    # These are extra helper functions that don't belong in a class
    #---------------------------------------------------------------------------#
    import getpass
    def root_test():
        ''' Simple test to see if we are running as root '''
        return True # removed for the time being as it isn't portable
        #return getpass.getuser() == "root"

    #--------------------------------------------------------------------------#
    # Helper Classes
    #--------------------------------------------------------------------------#
    class ConfigurationException(Exception):
        ''' Exception for configuration error '''

        def __init__(self, string):
            ''' Initializes the ConfigurationException instance

            :param string: The message to append to the exception
            '''
            Exception.__init__(self, string)
            self.string = string

        def __str__(self):
            ''' Builds a representation of the object

            :returns: A string representation of the object
            '''
            return 'Configuration Error: %s' % self.string

    class Configuration:
        '''
        Class used to parse configuration file and create and modbus
        datastore.

        The format of the configuration file is actually just a
        python pickle, which is a compressed memory dump from
        the scraper.
        '''

        def __init__(self, config):
            '''
            Trys to load a configuration file, lets the file not
            found exception fall through

            :param config: The pickled datastore
            '''
            try:
                self.file = open(config, "r")
            except Exception:
                raise ConfigurationException("File not found %s" % config)

        def parse(self):
            ''' Parses the config file and creates a server context
            '''
            handle = pickle.load(self.file)
            try: # test for existance, or bomb
                dsd = handle['di']
                csd = handle['ci']
                hsd = handle['hr']
                isd = handle['ir']
            except Exception:
                raise ConfigurationException("Invalid Configuration")
            slave = ModbusSlaveContext(d=dsd, c=csd, h=hsd, i=isd)
            return ModbusServerContext(slaves=slave)

    #--------------------------------------------------------------------------#
    # Main start point
    #--------------------------------------------------------------------------#
    def main():
        ''' Server launcher '''
        parser = OptionParser()
        parser.add_option("-c", "--conf",
                        help="The configuration file to load",
                        dest="file")
        parser.add_option("-D", "--debug",
                        help="Turn on to enable tracing",
                        action="store_true", dest="debug", default=False)
        (opt, arg) = parser.parse_args()

        # enable debugging information
        if opt.debug:
            try:
                server_log.setLevel(logging.DEBUG)
                protocol_log.setLevel(logging.DEBUG)
            except Exception, e:
        	    print "Logging is not supported on this system"

        # parse configuration file and run
        try:
            conf = Configuration(opt.file)
            StartTcpServer(context=conf.parse())
        except ConfigurationException, err:
            print err
            parser.print_help()

    #---------------------------------------------------------------------------#
    # Main jumper
    #---------------------------------------------------------------------------#
    if __name__ == "__main__":
        if root_test():
            main()
        else: print "This script must be run as root!"