def __init__(self, dev, userCmd, timeLim): """!Start disconnecting a device """ self.dev = dev self.userCmd = expandUserCmd(userCmd) self._timeLim = timeLim self._connTimer = Timer() self._addedConnCallback = False if self.dev.conn.isDisconnected: if self.dev.state != self.dev.Disconnected: self.dev.setState(self.dev.Disconnected, "socket disconnected") if not self.userCmd.isDone: self.userCmd.setState(self.userCmd.Done) return self.dev._ignoreConnCallback = True if self.dev.state != self.dev.Disconnected: self.dev.setState(self.dev.Disconnecting) if self.dev.conn.isConnected: initUserCmd = UserCmd(cmdStr="Init via device.DisconnectDevice", callFunc=self.initCallback, timeLim=timeLim) self.dev.init(userCmd=initUserCmd, timeLim=timeLim, getStatus=False) else: # not fully connected, so cannot send init, but not fully disconnected yet, so finish disconnecting textMsg = "%s connection state=%s; cannot initialize before disconnecting" % ( self.dev.name, self.dev.conn.state) self.dev.writeToUsers("w", "text=%s" % (quoteStr(textMsg), )) self.startDisconnect() return
def __init__(self, dev, userCmd, timeLim): """!Start disconnecting a device """ self.dev = dev self.userCmd = expandUserCmd(userCmd) self._timeLim = timeLim self._connTimer = Timer() self._addedConnCallback = False if self.dev.conn.isDisconnected: if self.dev.state != self.dev.Disconnected: self.dev.setState(self.dev.Disconnected, "socket disconnected") if not self.userCmd.isDone: self.userCmd.setState(self.userCmd.Done) return self.dev._ignoreConnCallback = True if self.dev.state != self.dev.Disconnected: self.dev.setState(self.dev.Disconnecting) if self.dev.conn.isConnected: initUserCmd = UserCmd(cmdStr="Init via device.DisconnectDevice", callFunc=self.initCallback, timeLim=timeLim) self.dev.init(userCmd=initUserCmd, timeLim=timeLim, getStatus=False) else: # not fully connected, so cannot send init, but not fully disconnected yet, so finish disconnecting textMsg = "%s connection state=%s; cannot initialize before disconnecting" % (self.dev.name, self.dev.conn.state) self.dev.writeToUsers("w", "text=%s" % (quoteStr(textMsg),)) self.startDisconnect() return
def showVersion(tccActor, userCmd): """ @param[in,out] tccActor tcc actor @param[in,out] userCmd user command """ kwStr = 'Version=%s' % (quoteStr(tcc.__version__),) userCmd.setState(userCmd.Done, hubMsg=kwStr)
def showOneDevConnStatus(self, dev, cmd=None, onlyOneUser=False, onlyIfNotConn=False): """!Show connection status for one device @param[in] dev device whose state is to be shown @param[in] cmd user command (twistedActor.UserCmd) @param[in] onlyOneUser if True only display the information to the commanding user @param[in] onlyIfNotConn only show information for devices that are disconnected """ if onlyIfNotConn and dev.conn.isConnected: return state, reason = dev.conn.fullState quotedReason = quoteStr(reason) #msgCode = "i" if dev.conn.isConnected else "w" if dev.conn.isConnected: msgCode = "i" else: msgCode = "w" msgStr = "%sConnState = %r, %s" % (dev.name, state, quotedReason) if onlyOneUser: self.writeToOneUser(msgCode, msgStr, cmd=cmd) else: self.writeToUsers(msgCode, msgStr, cmd=cmd)
def showVersion(self, cmd, onlyOneUser=False): """!Show actor version """ msgStr = "version=%s" % (quoteStr(self.version),) if onlyOneUser: self.writeToOneUser("i", msgStr, cmd=cmd) else: self.writeToUsers("i", msgStr, cmd=cmd)
def hubFormat(self): """Return (msgCode, msgStr) for output of status as a hub-formatted message""" msgCode = self._MsgCodeDict[self.state] msgInfo = [] if self._hubMsg: msgInfo.append(self._hubMsg) if self._textMsg: msgInfo.append("Text=%s" % (quoteStr(self._textMsg),)) msgStr = "; ".join(msgInfo) return (msgCode, msgStr)
def initCallback(self, initUserCmd): """!Callback for device initialization """ if not initUserCmd.isDone: return if initUserCmd.didFail: textMsg = "%s initialization failed: %s" % (self.dev.name, initUserCmd.textMsg,) self.dev.writeToUsers("w", "text=%s" % (quoteStr(textMsg),)) self.startDisconnect()
def _showReply(self, cmdVar): replyStr = cmdVar.lastReply.string if cmdVar.lastReply else None if not replyStr: return msgCode = { ":": "I", "E": "W", "F": "W", "!": "W", }.get(cmdVar.lastCode, cmdVar.lastCode) self.writeToUsers(msgCode, "%sReply=%s" % (self.name, quoteStr(replyStr),))
def initCallback(self, initUserCmd): """!Callback for device initialization """ if not initUserCmd.isDone: return if initUserCmd.didFail: textMsg = "%s initialization failed: %s" % ( self.dev.name, initUserCmd.textMsg, ) self.dev.writeToUsers("w", "text=%s" % (quoteStr(textMsg), )) self.startDisconnect()
def _showReply(self, cmdVar): replyStr = cmdVar.lastReply.string if cmdVar.lastReply else None if not replyStr: return msgCode = { ":": "I", "E": "W", "F": "W", "!": "W", }.get(cmdVar.lastCode, cmdVar.lastCode) self.writeToUsers(msgCode, "%sReply=%s" % ( self.name, quoteStr(replyStr), ))
def showOneDevConnStatus(self, dev, cmd=None, onlyOneUser=False, onlyIfNotConn=False): """Show connection status for one device""" if onlyIfNotConn and dev.conn.isConnected: return state, reason = dev.conn.fullState quotedReason = quoteStr(reason) #msgCode = "i" if dev.conn.isConnected else "w" if dev.conn.isConnected: msgCode = "i" else: msgCode = "w" msgStr = "%sConnState = %r, %s" % (dev.name, state, quotedReason) if onlyOneUser: self.writeToOneUser(msgCode, msgStr, cmd=cmd) else: self.writeToUsers(msgCode, msgStr, cmd=cmd)
def getKeyValMsg(self, textPrefix=""): """Get full message data as (msgCode, msgStr), where msgStr is in keyword-value format @param[in] textPrefix a prefix added to self._textMsg @return two values: - msgCode: message code (e.g. "W") - msgStr: message string: a combination of _textMsg and _hubMsg in keyword-value format. Warning: he "Text" keyword will be repeated if _textMsg is non-empty and _hubMsg contains "Text=" """ msgCode = self._MsgCodeDict[self._state] msgInfo = [] if self._hubMsg: msgInfo.append(self._hubMsg) if self._textMsg or textPrefix: msgInfo.append("text=%s" % (quoteStr(textPrefix + self._textMsg),)) msgStr = "; ".join(msgInfo) return (msgCode, msgStr)
def getKeyValMsg(self, textPrefix=""): """Get full message data as (msgCode, msgStr), where msgStr is in keyword-value format @param[in] textPrefix a prefix added to self._textMsg @return two values: - msgCode: message code (e.g. "W") - msgStr: message string: a combination of _textMsg and _hubMsg in keyword-value format. Warning: he "Text" keyword will be repeated if _textMsg is non-empty and _hubMsg contains "Text=" """ msgCode = self._MsgCodeDict[self._state] msgInfo = [] if self._hubMsg: msgInfo.append(self._hubMsg) if self._textMsg or textPrefix: msgInfo.append("text=%s" % (quoteStr(textPrefix + self._textMsg), )) msgStr = "; ".join(msgInfo) return (msgCode, msgStr)
def parseAndDispatchCmd(self, cmd): """Parse and dispatch a command Note: command name collisions are resolved as follows: - local commands (cmd_<foo> methods of this actor) - commands handled by devices - direct device access commands (device name) """ if not cmd.cmdBody: # echo to show alive self.writeToOneUser(":", "", cmd=cmd) return cmd.cmdVerb = "" cmd.cmdArgs = "" if cmd.cmdBody: res = cmd.cmdBody.split(None, 1) if len(res) > 1: cmd.cmdVerb, cmd.cmdArgs = res else: cmd.cmdVerb = res[0] # see if command is a local command cmdFunc = self.locCmdDict.get(cmd.cmdVerb) if cmdFunc is not None: # execute local command try: self.checkLocalCmd(cmd) retVal = cmdFunc(cmd) except CommandError, e: cmd.setState("failed", strFromException(e)) return except Exception, e: sys.stderr.write("command %r failed\n" % (cmd.cmdStr,)) sys.stderr.write("function %s raised %s\n" % (cmdFunc, strFromException(e))) traceback.print_exc(file=sys.stderr) quotedErr = quoteStr(strFromException(e)) msgStr = "Exception=%s; Text=%s" % (e.__class__.__name__, quotedErr) self.writeToUsers("f", msgStr, cmd=cmd)
dev = self.dev.nameDict.get(cmd.cmdVerb) if dev is not None: # command verb is the name of a device; # the command arguments are the string to send to the device devCmdStr = cmd.cmdArgs if dev and devCmdStr: try: dev.newCmd(devCmdStr, cmd=cmd) except CommandError, e: cmd.setState("failed", strFromException(e)) return except Exception, e: sys.stderr.write("command %r failed\n" % (cmd.cmdStr,)) sys.stderr.write("function %s raised %s\n" % (cmdFunc, strFromException(e))) traceback.print_exc(file=sys.stderr) quotedErr = quoteStr(strFromException(e)) msgStr = "Exception=%s; Text=%s" % (e.__class__.__name__, quotedErr) self.writeToUsers("f", msgStr, cmd=cmd) return self.writeToOneUser("f", "UnknownCommand=%s" % (cmd.cmdVerb,), cmd=cmd) def newUser(self, sock): fakeCmd = BaseActor.newUser(self, sock) self.showDevConnStatus(cmd=fakeCmd, onlyOneUser=True, onlyIfNotConn=True) def showDevConnStatus(self, cmd=None, onlyOneUser=False, onlyIfNotConn=False): """Show connection status for all devices""" for dev in self.dev.nameDict.itervalues(): self.showOneDevConnStatus(dev, onlyOneUser=onlyOneUser, onlyIfNotConn=onlyIfNotConn, cmd=cmd)
def parseAndDispatchCmd(self, cmd): """!Parse and dispatch a command @param[in] cmd user command (twistedActor.UserCmd) Duplicate command names are resolved such that the first match in this list is used: - local commands (cmd_<foo> methods of this actor) - commands handled by devices - direct device access commands (device name) """ if not cmd.cmdBody: # echo to show alive self.writeToOneUser(":", "", cmd=cmd) return # if a commandSet was supplied use it! if self.commandSet is not None: cmd.parsedCommand = self.commandSet.parse(cmd.cmdBody) cmd.cmdVerb = "" cmd.cmdArgs = "" if cmd.cmdBody: res = cmd.cmdBody.split(None, 1) if len(res) > 1: cmd.cmdVerb, cmd.cmdArgs = res else: cmd.cmdVerb = res[0] cmd.cmdVerb = cmd.cmdVerb.lower() # see if command is a local command cmdFunc = self.locCmdDict.get(cmd.cmdVerb) if cmdFunc is not None: # execute local command try: self.checkLocalCmd(cmd) retVal = cmdFunc(cmd) except CommandError as e: cmd.setState("failed", strFromException(e)) return except Exception as e: sys.stderr.write("command %r failed\n" % (cmd.cmdStr, )) sys.stderr.write("function %s raised %s\n" % (cmdFunc, strFromException(e))) traceback.print_exc(file=sys.stderr) quotedErr = quoteStr(strFromException(e)) msgStr = "Exception=%s; Text=%s" % (e.__class__.__name__, quotedErr) self.writeToUsers("f", msgStr, cmd=cmd) else: if not retVal and not cmd.isDone: cmd.setState("done") return # see if command is a device command dev = None devCmdStr = "" devCmdInfo = self.devCmdDict.get(cmd.cmdVerb) if devCmdInfo: # command verb is one handled by a device dev, devCmdVerb, cmdHelp = devCmdInfo devCmdStr = "%s %s" % (devCmdVerb, cmd.cmdArgs) if devCmdVerb else cmd.cmdArgs if dev and devCmdStr: try: dev.startCmd(devCmdStr, userCmd=cmd, timeLim=2) except CommandError as e: cmd.setState("failed", strFromException(e)) return except Exception as e: sys.stderr.write("command %r failed\n" % (cmd.cmdStr, )) sys.stderr.write("function %s raised %s\n" % (cmdFunc, strFromException(e))) traceback.print_exc(file=sys.stderr) quotedErr = quoteStr(strFromException(e)) msgStr = "Exception=%s; Text=%s" % (e.__class__.__name__, quotedErr) self.writeToUsers("f", msgStr, cmd=cmd) return self.writeToOneUser("f", "UnknownCommand=%s" % (cmd.cmdVerb, ), cmd=cmd)
def parseAndDispatchCmd(self, cmd): """!Parse and dispatch a command @param[in] cmd user command (twistedActor.UserCmd) Duplicate command names are resolved such that the first match in this list is used: - local commands (cmd_<foo> methods of this actor) - commands handled by devices - direct device access commands (device name) """ if not cmd.cmdBody: # echo to show alive self.writeToOneUser(":", "", cmd=cmd) return # if a commandSet was supplied use it! if self.commandSet is not None: cmd.parsedCommand = self.commandSet.parse(cmd.cmdBody) cmd.cmdVerb = "" cmd.cmdArgs = "" if cmd.cmdBody: res = cmd.cmdBody.split(None, 1) if len(res) > 1: cmd.cmdVerb, cmd.cmdArgs = res else: cmd.cmdVerb = res[0] cmd.cmdVerb = cmd.cmdVerb.lower() # see if command is a local command cmdFunc = self.locCmdDict.get(cmd.cmdVerb) if cmdFunc is not None: # execute local command try: self.checkLocalCmd(cmd) retVal = cmdFunc(cmd) except CommandError as e: cmd.setState("failed", strFromException(e)) return except Exception as e: sys.stderr.write("command %r failed\n" % (cmd.cmdStr,)) sys.stderr.write("function %s raised %s\n" % (cmdFunc, strFromException(e))) traceback.print_exc(file=sys.stderr) quotedErr = quoteStr(strFromException(e)) msgStr = "Exception=%s; Text=%s" % (e.__class__.__name__, quotedErr) self.writeToUsers("f", msgStr, cmd=cmd) else: if not retVal and not cmd.isDone: cmd.setState("done") return # see if command is a device command dev = None devCmdStr = "" devCmdInfo = self.devCmdDict.get(cmd.cmdVerb) if devCmdInfo: # command verb is one handled by a device dev, devCmdVerb, cmdHelp = devCmdInfo devCmdStr = "%s %s" % (devCmdVerb, cmd.cmdArgs) if devCmdVerb else cmd.cmdArgs if dev and devCmdStr: try: dev.startCmd(devCmdStr, userCmd=cmd, timeLim=2) except CommandError as e: cmd.setState("failed", strFromException(e)) return except Exception as e: sys.stderr.write("command %r failed\n" % (cmd.cmdStr,)) sys.stderr.write("function %s raised %s\n" % (cmdFunc, strFromException(e))) traceback.print_exc(file=sys.stderr) quotedErr = quoteStr(strFromException(e)) msgStr = "Exception=%s; Text=%s" % (e.__class__.__name__, quotedErr) self.writeToUsers("f", msgStr, cmd=cmd) return self.writeToOneUser("f", "UnknownCommand=%s" % (cmd.cmdVerb,), cmd=cmd)