Exemplo n.º 1
0
    def _apply_point_update(point_def, point_index, value):
        """
            Set an input point in the outstation database. This may send its PointValue to the Master.

        :param point_def: A PointDefinition.
        :param point_index: A numeric index for the point.
        :param value: A value to send (unwrapped, simple data type).
        """
        data_type = point_def.data_type
        if data_type == DATA_TYPE_ANALOG_INPUT:
            wrapped_val = opendnp3.Analog(float(value))
            if isinstance(value, bool) or not isinstance(value, numbers.Number):
                # Invalid data type
                raise DNP3Exception('Received {} value for {}.'.format(type(value), point_def))
        elif data_type == DATA_TYPE_BINARY_INPUT:
            wrapped_val = opendnp3.Binary(value)
            if not isinstance(value, bool):
                # Invalid data type
                raise DNP3Exception('Received {} value for {}.'.format(type(value), point_def))
        else:
            # The agent supports only DNP3's Analog and Binary point types at this time.
            raise DNP3Exception('Unsupported point type {}'.format(data_type))
        if wrapped_val is not None:
            DNP3Outstation.apply_update(wrapped_val, point_index)
        _log.debug('Sent DNP3 point {}, value={}'.format(point_def, wrapped_val.value))
Exemplo n.º 2
0
    def _apply_point_update(point_def, point_index, value):
        """
            Set an input point in the outstation database. This may send its PointValue to the Master.

        :param point_def: A PointDefinition.
        :param point_index: A numeric index for the point.
        :param value: A value to send (unwrapped, simple data type).
        """
        data_type = point_def.data_type
        if data_type == DATA_TYPE_ANALOG_INPUT:
            wrapped_val = opendnp3.Analog(float(value))
            if isinstance(value,
                          bool) or not isinstance(value, numbers.Number):
                # Invalid data type
                raise DNP3Exception('Received {} value for {}.'.format(
                    type(value), point_def))
        elif data_type == DATA_TYPE_BINARY_INPUT:
            wrapped_val = opendnp3.Binary(value)
            if not isinstance(value, bool):
                # Invalid data type
                raise DNP3Exception('Received {} value for {}.'.format(
                    type(value), point_def))
        else:
            # The agent supports only DNP3's Analog and Binary point types at this time.
            raise DNP3Exception('Unsupported point type {}'.format(data_type))
        if wrapped_val is not None:
            DNP3Outstation.apply_update(wrapped_val, point_index)
        _log.debug('Sent DNP3 point {}, value={}'.format(
            point_def, wrapped_val.value))
Exemplo n.º 3
0
    def _configure_parameters(self, contents):
        """
            Initialize/Update the DNP3 agent configuration.

            DNP3Agent configuration parameters (the MesaAgent subclass has some more):

            points: (string) A JSON structure of point definitions to be loaded.
            point_topic: (string) Message bus topic to use when publishing DNP3 point values.
                        Default: mesa/point.
            outstation_status_topic: (string) Message bus topic to use when publishing outstation status.
                        Default: mesa/outstation_status.
            local_ip: (string) Outstation's host address (DNS resolved).
                        Default: 0.0.0.0.
            port: (integer) Outstation's port number - the port that the remote endpoint (Master) is listening on.
                        Default: 20000.
            outstation_config: (dictionary) Outstation configuration parameters. All are optional.
                Parameters include:
                    database_sizes: (integer) Size of each DNP3 database buffer.
                                Default: 10000.
                    event_buffers: (integer) Size of the database event buffers.
                                Default: 10.
                    allow_unsolicited: (boolean) Whether to allow unsolicited requests.
                                Default: True.
                    link_local_addr: (integer) Link layer local address.
                                Default: 10.
                    link_remote_addr: (integer) Link layer remote address.
                                Default: 1.
                    log_levels: List of bit field names (OR'd together) that filter what gets logged by DNP3.
                                Default: [NORMAL].
                                Possible values: ALL, ALL_APP_COMMS, ALL_COMMS, NORMAL, NOTHING.
                    threads_to_allocate: (integer) Threads to allocate in the manager's thread pool.
                                Default: 1.
        """
        config = self.default_config.copy()
        config.update(contents)
        self.points = config.get('points', [])
        self.point_topic = config.get('point_topic', DEFAULT_POINT_TOPIC)
        self.outstation_status_topic = config.get('outstation_status_topic', DEFAULT_OUTSTATION_STATUS_TOPIC)
        self.local_ip = config.get('local_ip', DEFAULT_LOCAL_IP)
        self.port = int(config.get('port', DEFAULT_PORT))
        self.outstation_config = config.get('outstation_config', {})
        _log.debug('DNP3Agent configuration parameters:')
        _log.debug('\tpoints type={}'.format(type(self.points)))
        _log.debug('\tpoint_topic={}'.format(self.point_topic))
        _log.debug('\toutstation_status_topic={}'.format(self.outstation_status_topic))
        _log.debug('\tlocal_ip={}'.format(self.local_ip))
        _log.debug('\tport={}'.format(self.port))
        _log.debug('\toutstation_config={}'.format(self.outstation_config))
        self.load_point_definitions()
        DNP3Outstation.set_agent(self)
        return config
Exemplo n.º 4
0
 def start_outstation(self):
     """Start the DNP3Outstation instance, kicking off communication with the DNP3 Master."""
     _log.info('Starting DNP3Outstation')
     self.publish_outstation_status('starting')
     self.application = DNP3Outstation(self.local_ip, self.port,
                                       self.outstation_config)
     self.application.start()
     self.publish_outstation_status('running')
Exemplo n.º 5
0
 def onstart(self, sender, **kwargs):
     """Start the DNP3Outstation instance, kicking off communication with the DNP3 Master."""
     self._configure_parameters(self.default_config)
     _log.info('Starting DNP3Outstation')
     self.publish_outstation_status('starting')
     self.application = DNP3Outstation(self.local_ip, self.port, self.outstation_config)
     self.application.start()
     self.publish_outstation_status('running')
Exemplo n.º 6
0
    def _set_point(self, point_name, value):
        """
            (Internal) Set the value of a given input point (no debug trace).

        @param point_name: The VOLTTRON point name of a DNP3 PointDefinition.
        @param value: The value to set. The value's data type must match the one in the DNP3 PointDefinition.
        """
        point_properties = self.volttron_points.get(point_name, {})
        data_type = point_properties.get('data_type', None)
        index = point_properties.get('index', None)
        try:
            if data_type == DATA_TYPE_ANALOG_INPUT:
                wrapped_value = opendnp3.Analog(value)
            elif data_type == DATA_TYPE_BINARY_INPUT:
                wrapped_value = opendnp3.Binary(value)
            else:
                raise Exception('Unexpected data type for DNP3 point named {0}'.format(point_name))
            DNP3Outstation.apply_update(wrapped_value, index)
        except Exception as e:
            raise DNP3Exception(e.message)
Exemplo n.º 7
0
    def _set_point(self, point_name, value):
        """
            (Internal) Set the value of a given input point (no debug trace).

        @param point_name: The VOLTTRON point name of a DNP3 PointDefinition.
        @param value: The value to set. The value's data type must match the one in the DNP3 PointDefinition.
        """
        point_properties = self.volttron_points.get(point_name, {})
        group = point_properties.get('group', None)
        index = point_properties.get('index', None)
        point_type = PointDefinition.point_type_for_group(group)
        try:
            if point_type == POINT_TYPE_ANALOG_INPUT:
                wrapped_value = opendnp3.Analog(value)
            elif point_type == POINT_TYPE_BINARY_INPUT:
                wrapped_value = opendnp3.Binary(value)
            else:
                raise Exception('Unexpected data type for DNP3 point named {0}'.format(point_name))
            DNP3Outstation.apply_update(wrapped_value, index)
        except Exception as e:
            raise DNP3Exception(e.message)