def handle_msg(self, payload):
        """
        Handle message for network plugin protocol

        :param payload: Received message
        :type payload: dict
        :return: Response to send (if set)
        :rtype: None | dict
        """
        self.debug(u"\n{}".format(pformat(payload)))
        msg = payload['msg']
        res = {
            'msg': msg,
            'error': ""
        }
        if msg == "plugin_list":
            res['plugin_names'] = []
            # Generate list of plugins available for frontend
            for plugin in self.controller.plugins:
                # Limit to plugins that work with this
                if isinstance(plugin, SettablePlugin):
                    res['plugin_names'].append(plugin.name)
            return res
        elif msg == "plugin_get":
            res['plugin'] = {}
            plugin_name = payload.get('plugin_name')
            plugin, err = self._plugin_get(plugin_name)
            if not plugin:
                res['error'] = err
                return res
            res['plugin_name'] = plugin_name
            res['plugin'] = plugin.get_info()
            return res
        elif msg == "plugin_resource_list":
            res['resource_names'] = []
            plugin_name = payload.get('plugin_name')
            plugin, err = self._plugin_get(plugin_name)
            if not plugin:
                res['error'] = err
                return res
            res['plugin_name'] = plugin_name
            try:
                res['resource_names'] = plugin.resource_get_list()
            except PluginException as e:
                if str(e) == "No resource path set":
                    self.debug(
                        u"Plugin '{}' has no resources".format(plugin.name)
                    )
                else:
                    self.exception(
                        u"Failed to get resource list for plugin '{}'".format(
                            plugin.name
                        )
                    )
            return res
        elif msg == "plugin_resource_get":
            res['resource'] = {}
            plugin_name = payload.get('plugin_name')
            resource_name = payload.get('resource_name')
            if not resource_name:
                res['error'] = "Resource name not set"
                return res
            plugin, err = self._plugin_get(plugin_name)
            if not plugin:
                res['error'] = err
                return res
            res['plugin_name'] = plugin_name
            res['resource_name'] = resource_name
            res['resource'] = dict(plugin.resource_get(resource_name))
            if "path" in res['resource']:
                del res['resource']['path']
            return res
        elif msg == "plugin_resource_load":
            res['resource_data'] = ""
            plugin_name = payload.get('plugin_name')
            resource_name = payload.get('resource_name')
            if not resource_name:
                res['error'] = "Resource name not set"
                return res
            plugin, err = self._plugin_get(plugin_name)
            if not plugin:
                res['error'] = err
                return res
            res['plugin_name'] = plugin_name
            res['resource_name'] = resource_name
            resource_dict = plugin.resource_get(resource_name)
            if not resource_dict:
                res['error'] = u"Resource '{}' not found".format(resource_name)
                return res
            self.debug(u"Resource {}".format(resource_dict))
            try:
                with open(resource_dict['path'], 'rb') as f:
                    res['resource_data'] = base64.b64encode(f.read())
            except:
                self.exception(
                    u"Failed to load '{}'".format(resource_dict['path'])
                )
                res['error'] = u"Failed to load"
            return res
        elif msg == "plugin_data_get":
            plugin_name = payload.get('plugin_name')
            plugin, err = self._plugin_get(plugin_name)
            if not plugin:
                res['error'] = err
                return res
            res['plugin_name'] = plugin_name
            res['data'] = plugin.get_data()
            return res
        elif msg == "plugin_data_set":
            plugin_name = payload.get('plugin_name')
            plugin, err = self._plugin_get(plugin_name)
            if not plugin:
                res['error'] = err
                return res
            res['plugin_name'] = plugin_name
            data = payload.get('data')
            if not data:
                res['error'] = u"No data provided"
                return res
            try:
                plugin.on_config(data)
            except NotImplementedError:
                res['error'] = u"Plugin does not support setting data"
                return res
            except:
                self.exception(
                    u"Failed to set data for {}".format(plugin_name)
                )
                res['error'] = "Failed to set data"
                return res
            return {}
        else:
            self.error(u"Unknown cmd '{}'\n{}".format(msg, payload))
        return {}
Handle message for network plugin protocol

        :param payload: Received message
        :type payload: dict
        :return: Response to send (if set)
        :rtype: None | dict