def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.group: iofun.out("group to remove not set, aborting!") return if not self.linkAddr: iofun.out("address to remove not set, aborting!") return linkType = (1 << 6) if self.isController else 0 linkType |= (1 << 1) # high water mark linkType |= (1 << 5) # unused bit, but seems to be always 1 # linkType |= (1 << 7) # valid record searchRec = { "offset": 0, "addr": self.linkAddr, "type": linkType, "group": self.group, "data": self.data } rec = db.findActiveRecord(searchRec) if not rec: iofun.out("no matching found record, no action taken!") return iofun.out("erasing active record at offset: " + format(rec["offset"], '04x')) self.dev.setRecord(rec["offset"], rec["addr"], rec["group"], rec["type"] & 0x3f, rec["data"])
def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.linkAddr: iofun.out("address to remove not set, aborting!") return if not self.dev: iofun.out("no valid device set, aborting!") return linkType = 0 searchRec = { "offset": 0, "addr": self.linkAddr, "type": linkType, "group": 0, "data": [0, 0, 0] } records = db.findActiveRecords(searchRec, True, False, False) if not records: iofun.out("no matching record found, no action taken!") return iofun.out("found active records: ") for rec in records: db.dumpRecord(rec, "removing record: ") self.dev.setRecord(rec["offset"], rec["addr"], rec["group"], rec["type"] & 0x3f, rec["data"]) time.sleep(5.0)
def sendOff(self, group): """sendOff(group) sends ALLLink broadcast OFF message to group "group" """ msg = message.createStdMsg(InsteonAddress("00.00.00"), 0x0f, 0x13, 0xFF, group) iofun.writeMsg(msg) iofun.out("sent msg: " + msg.toString())
def help(obj=None): """help(object) prints out help for object, e.g. help(modem)""" if obj is not None: sep = '\n' if isinstance(obj, (types.FunctionType)): if obj.__doc__ is None: iofun.out("No documentation for \"" + obj.__name__ + "\"") return iofun.out(obj.__doc__) elif isinstance(obj, (types.ClassType, types.ObjectType)): if obj.__doc__ is None: iofun.out("No documentation for \"" + obj.__class__.__name__ + "\"") return iofun.out(obj.__doc__) docList = [ getattr(obj, method).__doc__ for method in dir(obj) if callable(getattr(obj, method)) and getattr(obj, method).__doc__ ] if len(docList) == 0: return maxMethodLen = max([len(doc.split(sep)[0]) for doc in docList]) iofun.out("\n".join([ "%s %s" % (doc.split(sep)[0].ljust(maxMethodLen + 1), " ".join( doc.split(sep)[1:]).strip()) for doc in docList ])) else: out("-------Welcome to the Insteon Terminal-------") out("to get a list of available functions, type '?'") out("to get help, type help(funcName) or help(objectName)") out("for example: help(Modem2413U)") out("to quit, type 'quit()'")
def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.dev: iofun.out("no valid device set, aborting!") return linkType = 0 searchRec = { "offset": 0, "addr": InsteonAddress("00.00.00"), "type": linkType, "group": 0, "data": [0, 0, 0] } records = db.findAllRecords(searchRec, False, False, False) if not records: iofun.out("no matching record found, no action taken!") return iofun.out("found active records: ") i = 0 for rec in reversed(records): if self.numRecords > 0 and i >= self.numRecords: break db.dumpRecord(rec, " removing record:") self.dev.setRecord(rec["offset"], InsteonAddress("00.00.00"), 0, 0, [0, 0, 0]) time.sleep(5.0) i = i + 1 time.sleep(1) # wait for one second iofun.out("complete")
def databaseComplete(self, db): iofun.out("database complete, analyzing...") linkType = (1 << 6) if self.isController else 0 linkType |= (1 << 1) # set high water mark linkType |= (1 << 5) # unused bit, but seems to be always 1 linkType |= (1 << 7) # valid record searchRec = {"offset" : 0, "addr": self.linkAddr, "type" : linkType, "group" : self.group, "data" : self.data} rec = db.findActiveRecord(searchRec) if rec: db.dumpRecord(rec, "found active record:"); iofun.out("already linked, no action taken!") return searchRec["type"] = linkType; # match all but data rec = db.findInactiveRecord(searchRec, True, True, False) if not rec: # match address rec = db.findInactiveRecord(searchRec, True, False, False) if not rec: # match any unused record rec = db.findInactiveRecord(searchRec, False, False, False) if rec: db.dumpRecord(rec, "reusing inactive record:") self.dev.setRecord(rec["offset"], self.linkAddr, self.group, linkType, self.data) iofun.out("link record added!") else: iofun.out("no unused records, adding one at the end!") newOffset = self.addEmptyRecordAtEnd(db) iofun.out("now setting the new record!") self.dev.setRecord(newOffset, self.linkAddr, self.group, linkType, self.data)
def help(obj = None): """help(object) prints out help for object, e.g. help(modem)""" if obj is not None : sep='\n' if isinstance(obj, (types.FunctionType)): if obj.__doc__ is None : iofun.out("No documentation for \"" + obj.__name__ + "\"") return iofun.out(obj.__doc__) elif isinstance(obj, (types.ClassType, types.ObjectType)): if obj.__doc__ is None : iofun.out("No documentation for \"" + obj.__class__.__name__ + "\"") return iofun.out(obj.__doc__) docList = [getattr(obj, method).__doc__ for method in dir(obj) if callable(getattr(obj, method)) and getattr(obj, method).__doc__] if len(docList) == 0: return maxMethodLen = max([len(doc.split(sep)[0]) for doc in docList]) iofun.out("\n".join(["%s %s" % (doc.split(sep)[0].ljust(maxMethodLen + 1), " ".join(doc.split(sep)[1:]).strip()) for doc in docList])) else: out("-------Welcome to the Insteon Terminal-------") out("to get a list of available functions, type '?'") out("to get help, type help(funcName) or help(objectName)") out("for example: help(Modem2413U)") out("to quit, type 'quit()'")
def getdb(self): """getdb() download the device database and print it on the console""" iofun.out("getting db, be patient!") self.dbbuilder.clear() self.dbbuilder.start() self.dbbuilder.wait() self.dbbuilder.db.dump()
def readdb(self): """readdb() blocking wait for the device database and return it""" iofun.out("reading device db, be patient!") self.dbbuilder.clear() self.dbbuilder.start() isSane = self.dbbuilder.wait() return self.dbbuilder.db, isSane
def databaseComplete(self, db): iofun.out("database complete, removing last record") above, stopaddr, below = db.findStopRecordAddresses() if (above == 0): iofun.out("db already empty!") else: self.dev.setRecord(above, InsteonAddress("00.00.00"), 0x00, 0x00, [0, 0, 0])
def removeLastRecords(self, num): """removeLastRecord() removes num last records in the link database""" if not num: iofun.out("num must be set to > 0, aborting!") return if num < 1: iofun.out("num must be set to > 0, aborting!") return self.modifyDB(LastNRecordRemover(self, num))
def databaseComplete(self, db): iofun.out("database complete, replacing...") mask = 0x02; searchRec = {"offset" : 0, "addr": self.oldAddr, "type" : (1<<1), "group" : 0, "data" : []} recs = db.findRecord(searchRec, mask, True, False, False, True); for rec in recs: db.dumpRecord(rec, "replacing: "); self.dev.setRecord(rec["offset"], self.newAddr, rec["group"], rec["type"], rec["data"]) time.sleep(1) # wait for one second if not recs: iofun.out("no matching records found, nothing to replace!") return
def databaseComplete(self, db): iofun.out("database complete, analyzing...") linkType = (1 << 6) if self.isController else 0 linkType |= (1 << 1) # set high water mark linkType |= (1 << 5) # unused bit, but seems to be always 1 linkType |= (1 << 7) # valid record searchRec = {"offset" : 0, "addr": self.linkAddr, "type" : linkType, "group" : self.group, "data" : self.data} rec = db.findActiveRecord(searchRec) if rec: db.dumpRecord(rec, "found active record:"); self.dev.setRecord(rec["offset"], rec["addr"], rec["group"], rec["type"], self.data) else: iofun.out("no matching record found, check your data!") return
def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.group: iofun.out("group to remove not set, aborting!") return if not self.linkAddr: iofun.out("address to remove not set, aborting!") return linkType = (1 << 6) if self.isController else 0 linkType |= (1 << 1) # high water mark linkType |= (1 << 5) # unused bit, but seems to be always 1 # linkType |= (1 << 7) # valid record searchRec = {"offset" : 0, "addr": self.linkAddr, "type" : linkType, "group" : self.group, "data" : self.data} rec = db.findActiveRecord(searchRec); if not rec: iofun.out("no matching found record, no action taken!") return iofun.out("erasing active record at offset: " + format(rec["offset"], '04x')) self.dev.setRecord(rec["offset"], rec["addr"], rec["group"], rec["type"] & 0x3f, rec["data"]);
def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.linkAddr: iofun.out("address to remove not set, aborting!") return if not self.dev: iofun.out("no valid device set, aborting!") return linkType = 0 searchRec = {"offset" : 0, "addr": self.linkAddr, "type" : linkType, "group" : 0, "data" : [0,0,0]} records = db.findActiveRecords(searchRec, True, False, False); if not records: iofun.out("no matching record found, no action taken!") return iofun.out("found active records: "); for rec in records: db.dumpRecord(rec, "removing record: ") self.dev.setRecord(rec["offset"], rec["addr"], rec["group"], rec["type"] & 0x3f, rec["data"]); time.sleep(5.0)
def processMsg(self, msg): if msg.isExtended(): light = msg.getByte("userData11") & 0xFF battery = msg.getByte("userData12") & 0xFF iofun.out(self.label + " light level: " + format(light, 'd') + " battery level: " + format(battery, 'd')) return 1 else: iofun.out(self.label + " unexpected direct message: " + msg.toString()) return 0 iofun.out(self.label + " = " + format(tmp, '02d')) return 1
def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.dev: iofun.out("no valid device set, aborting!") return linkType = 0 searchRec = {"offset" : 0, "addr": InsteonAddress("00.00.00"), "type" : linkType, "group" : 0, "data" : [0,0,0]} records = db.findAllRecords(searchRec, False, False, False) if not records: iofun.out("no matching record found, no action taken!") return iofun.out("found active records: ") i = 0 for rec in reversed(records): if self.numRecords > 0 and i > self.numRecords: break db.dumpRecord(rec, " removing record:") self.dev.setRecord(rec["offset"], InsteonAddress("00.00.00"), 0, 0, [0, 0, 0]); time.sleep(5.0) i = i + 1
def databaseComplete(self, db): iofun.out("database complete, moving...") mask = 0x02 searchRec = { "offset": self.oldOffset, "addr": InsteonAddress("00.00.00"), "type": (1 << 1), "group": 0, "data": [] } recs = db.findRecord(searchRec, mask, False, False, False, True) for rec in recs: if rec["offset"] == self.oldOffset: db.dumpRecord(rec, "oldRecord: ") oldRec = rec searchRec = { "offset": self.newOffset, "addr": InsteonAddress("00.00.00"), "type": (1 << 1), "group": 0, "data": [] } recs = db.findRecord(searchRec, mask, False, False, False, True) for rec in recs: if rec["offset"] == self.newOffset: db.dumpRecord(rec, "newRecord: ") newRec = rec if not oldRec: iofun.out("no source record found, nothing to do!") return if not newRec: iofun.out("no target record found, nothing to do!") return self.dev.setRecord(newRec["offset"], oldRec["addr"], oldRec["group"], oldRec["type"], oldRec["data"]) time.sleep(1) # wait for one second iofun.out("complete")
def processMsg(self, msg): tmp = msg.getByte("command1") & 0xFF if msg.isAckOfDirect(): iofun.out(self.name + " got ack!") return 0 if msg.isBroadcast() and tmp == 0x01: iofun.out(self.name + " got info: " + msg.toString()) addr = msg.getAddress("toAddress"); devCat, subCat, fwv = [addr.getHighByte(), addr.getMiddleByte(), addr.getLowByte()] hwv = msg.getByte("command2") & 0xFF; iofun.out(self.name + " dev cat: " + format(devCat, '02x') + " subcat: " + format(subCat, '02x') + " firmware: " + format(fwv, '02x') + " hardware: " + format(hwv, '02x')) return 1 return 0
def databaseIncomplete(self, db): iofun.out("database incomplete, reload() and retry!")
def listDevices(): for name, dev in devNameMap.iteritems(): iofun.out(format(name, '30s') + " " + dev.getAddress())
def processMsg(self, msg): if msg.isExtended(): LEDBrightness = msg.getByte("userData3") & 0xFF rawmotioncountdown = msg.getByte("userData4") & 0xFF motioncountdownsec = (rawmotioncountdown + 1) * 30 rawlightsensitivity = msg.getByte("userData5") & 0xFF rawflags = msg.getByte("userData6") & 0xFF flags = bin(msg.getByte("userData6") & 0xFF)[2:].zfill(8) light = msg.getByte("userData11") & 0xFF battery = msg.getByte("userData12") & 0xFF # Bit 0 if (rawflags & 0b00000001 == 1): cleanupreport = "Unknown" else: cleanupreport = "Unknown" # Bit 1 if (rawflags & 0b00000010 == 2): onoffmode = "Send on and after timeout send off" else: onoffmode = "Only sends on commands" # Bit 2 if (rawflags & 0b00000100 == 4): daynightmode = "Send commands at day and night" else: daynightmode = "Sends comands only when dark is sensed (as set by light/dark threshold)" # Bit 3 if (rawflags & 0b00001000 == 8): ledonoff = "LED blinks when motion is detected at brightness set by LED Brightness" else: ledonoff = "LED does not blink with motion" # Bit 4 if (rawflags & 0b00010000 == 16): occmode = "Sends repeated On commands whenever motion is detected" else: occmode = "Sends only 1 On command until timeout set by Motion Countdown time" # Bit 5 if (rawflags & 0b00100000 == 32): unk1 = "Unknown" else: unk1 = "Unknown" # Bit 6 if (rawflags & 0b01000000 == 64): ffgrp = "Unknown" else: ffgrp = "Unknown" # Bit 7 if (rawflags & 0b10000000 == 128): plock = "Unknown" else: plock = "Unknown" iofun.out(self.label + " LED Brightness (if flag set on): " + format(LEDBrightness, 'd')) iofun.out(" Light level: " + format(light, 'd') + " Light/Dark threshold: " + format(rawlightsensitivity, 'd')) iofun.out(" Battery level: " + format(battery, 'd')) iofun.out(" Motion Countdown Set Value: " + format(rawmotioncountdown, 'd')) iofun.out(" Motion Countdown Time: " + format(motioncountdownsec, 'd') + "seconds") iofun.out(" Configuration Byte (hex): " + format(rawflags, 'X')) iofun.out(" Configuration Byte (binary): " + format(flags, 'd')) iofun.out(" Bit 0: Unknown") iofun.out(" Bit 1: 1 = On/Off Mode, 0 = On Only Mode") iofun.out(" Bit 2: 1 = Day/Night Mode, 0 = Night Only Mode") iofun.out(" Bit 3: 1 = Motion LED on, 0 = Motion LED Off") iofun.out(" Bit 4: 1 = Occupancy Mode on, 0 = Occupancy Mode Off") iofun.out(" Bit 5: Unknown") iofun.out(" Bit 6: Unknown") iofun.out(" Bit 7: Unknown") iofun.out("\nCurrent Config Byte Setting:") iofun.out("\n\t" + cleanupreport + "\n\t" + onoffmode + "\n\t" + daynightmode + "\n\t" + ledonoff + "\n\t" + occmode + "\n\t" + unk1 + "\n\t" + ffgrp + "\n\t" + plock) return 1 else: iofun.out(self.label + " unexpected direct message: " + msg.toString()) return 0 iofun.out(self.label + " = " + format(tmp, '02d')) return 1
def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.linkAddr: iofun.out("address to remove not set, aborting!") return if not self.dev: iofun.out("no valid device set, aborting!") return linkType = 0 linkType |= (1 << 1) # high water mark linkType |= (1 << 5) # unused bit, but seems to be always 1 searchRec = {"offset" : 0, "addr": self.linkAddr, "type" : linkType, "group" : 0, "data" : [0,0,0]} iofun.out("database has " + format(db.getNumberOfRecords(), 'd') + " records"); records = db.findActiveRecords(searchRec, True, False, False); if not records: iofun.out("no matching record found, no action taken!") return iofun.out("found active " + format(len(records), 'd') + " records."); for rec in records: self.dev.modifyRecord(rec["addr"], rec["group"], 0x80, 0x00, [0,0,0], "remove record") time.sleep(5.0)
def __modifyModemDB(self, listener): self.dbbuilder.setListener(listener) # after db download complete, listener will perform action iofun.out("getting db, be patient!") self.dbbuilder.clear() self.dbbuilder.start()
def databaseIncomplete(self, db): iofun.out("database incomplete, retrying!") self.dev.dbbuilder.setListener(self) self.dev.getdb()
def out(msg=""): """out("text") prints text to the console""" iofun.out(msg)
def removeController(self, addr, group): """removeController(addr, group) could not be implemented for the modem. Use removeResponderOrController() instead!""" iofun.out("removeController(addr, group) could not be implemented" + " for the modem. Use removeResponderOrController() instead!")
def processMsg(self, msg): if not msg.isExtended(): if (msg.getByte("command1") == 0x2E): iofun.out(self.label + " got ack: " + msg.toString()) else: iofun.out(self.label + " got unexpected: " + msg.toString()) return 0 # still need to wait for ext message to come in # got an extended message iofun.out(self.label + " got " + msg.toString()) # # iofun.out(self.label + " on mask: " + '{0:08b}'.format(msg.getByte("userData3") & 0xFF)) iofun.out(self.label + " off mask: " + '{0:08b}'.format(msg.getByte("userData4") & 0xFF)) iofun.out(self.label + " non-toggle mask bits: " + '{0:08b}'.format(msg.getByte("userData10") & 0xFF)) iofun.out(self.label + " LED status bits: " + '{0:08b}'.format(msg.getByte("userData11") & 0xFF)) iofun.out(self.label + " X10 all bit mask: " + '{0:08b}'.format(msg.getByte("userData12") & 0xFF)) iofun.out(self.label + " on/off bit mask: " + '{0:08b}'.format(msg.getByte("userData13") & 0xFF)) iofun.out(self.label + " trigger group bit mask: " + '{0:08b}'.format(msg.getByte("userData14") & 0xFF)) iofun.out(self.label + " X10 house code: " + format(msg.getByte("userData5") & 0xFF, '03x')) iofun.out(self.label + " X10 unit: " + format(msg.getByte("userData6") & 0xFF, '03x')) iofun.out(self.label + " ramp rate: " + format(msg.getByte("userData7") & 0xFF, '03d')) iofun.out(self.label + " on level: " + format(msg.getByte("userData8") & 0xFF, '03d')) iofun.out(self.label + " LED brightness: " + format(msg.getByte("userData9") & 0xFF, '03d')) return 1
def processMsg(self, msg): tmp = msg.getByte("command2") & 0xFF iofun.out(self.label + " = " + format(tmp, "02d") + " = " + "{0:08b}".format(tmp)) return 1
def processMsg(self, msg): iofun.out(self.label + " got msg: " + msg.toString()) return 1
def out(msg = ""): iofun.out(msg)
def out(msg = ""): """out("text") prints text to the console""" iofun.out(msg)
def out(msg=""): iofun.out(msg)
def databaseIncomplete(self, db): iofun.out("databaseIncomplete() not implemented!")
def databaseComplete(self, db): iofun.out("database complete, analyzing...") if not self.linkAddr: iofun.out("address to remove not set, aborting!") return if not self.dev: iofun.out("no valid device set, aborting!") return linkType = 0 linkType |= (1 << 1) # high water mark linkType |= (1 << 5) # unused bit, but seems to be always 1 searchRec = { "offset": 0, "addr": self.linkAddr, "type": linkType, "group": 0, "data": [0, 0, 0] } iofun.out("database has " + format(db.getNumberOfRecords(), 'd') + " records") records = db.findActiveRecords(searchRec, True, False, False) if not records: iofun.out("no matching record found, no action taken!") return iofun.out("found active " + format(len(records), 'd') + " records.") for rec in records: self.dev.modifyRecord(rec["addr"], rec["group"], 0x80, 0x00, [0, 0, 0], "remove record") time.sleep(5.0)
def processMsg(self, msg): iofun.out( time.strftime("%H:%M:%S") + ": " + self.label + " got msg: " + msg.toString()) return 1
def processMsg(self, msg): tmp = msg.getByte("command2") & 0xFF iofun.out(self.label + " = " + format(tmp, '02d')) return 1
def getdb(self): """getdb() download the device database and print it on the console""" iofun.out("getting db, be patient!") self.dbbuilder.clear() self.dbbuilder.start()
def processMsg(self, msg): iofun.out(time.strftime("%H:%M:%S") + ": " + self.label + " got msg: " + msg.toString()) return 1
def processMsg(self, msg): if msg.isExtended(): LEDBrightness = msg.getByte("userData3") & 0xFF rawflags = msg.getByte("userData6") & 0xFF flags = bin(msg.getByte("userData6") & 0xFF)[2:].zfill(8) # Bit 0 if (rawflags & 0b00000001 == 1): cleanupreport = "Send Cleanup Report" else: cleanupreport = "Don't Send Cleanup Report" # Bit 1 if (rawflags & 0b00000010 == 2): readjumper = "Don't Read the jumper" else: readjumper = "Read The Jumper" # Bit 2 if (rawflags & 0b00000100 == 4): wetdrygroups = "Send Dry on Group 1 ON/Wet on Group 2 ON" else: wetdrygroups = "Send both Dry and Wet on Group 1 (On=Dry and Off=Wet)" # Bit 3 if (rawflags & 0b00001000 == 8): wetrepeat = "Send Repeated Wet Commands" else: wetrepeat = "Don't Send Repeated Wet Commands" # Bit 4 if (rawflags & 0b00010000 == 16): dryrepeat = "Send Repeated Dry Commands" else: dryrepeat = "Don't Send Repeated Dry Commands" # Bit 5 if (rawflags & 0b00100000 == 32): ledonoff = "LED does not blink on transmission" else: ledonoff = "LED blinks on transmission" # Bit 6 if (rawflags & 0b01000000 == 64): ffgrp = "Link to FF Group" else: ffgrp = "Don't link to FF Group" # Bit 7 if (rawflags & 0b10000000 == 128): plock = "Programming lock on" else: plock = "Programming lock off" iofun.out(self.label + " LED Brightness (if flag set on): " + format(LEDBrightness, 'd')) iofun.out(" Configuration Byte (hex): " + format(rawflags, 'X')) iofun.out(" Configuration Byte (binary): " + format(flags, 'd')) iofun.out( " Bit 0: 1 = Send Cleanup Report, 0 = Don't Send Cleanup Report" ) iofun.out(" Bit 1: 1 = Don't Read the Jumper, 0 = Read the Jumper") iofun.out( " Bit 2: 1 = Send Dry on Group 1 ON/Wet on Group 2 ON, 0 = Send both Dry and Wet on Group 1 (On=Dry and Off=Wet)" ) iofun.out( " Bit 3: 1 = Send Repeated Wet Commands, 0 = Don't Send Repeated Wet Commands" ) iofun.out( " Bit 4: 1 = Send Repeated Dry Commands, 0 = Don't Send Repeated Dry Commands" ) iofun.out( " Bit 5: 1 = LED does not blink on transmission, 0 = LED blinks on transmission" ) iofun.out( " Bit 6: 1 = Link to FF Group, 0 = Don't link to FF Group") iofun.out( " Bit 7: 1 = Programming lock on, 0 = Programming Lock off") iofun.out("\nCurrent Config Byte Setting:") iofun.out("\n\t" + cleanupreport + "\n\t" + readjumper + "\n\t" + wetdrygroups + "\n\t" + wetrepeat + "\n\t" + dryrepeat + "\n\t" + ledonoff + "\n\t" + ffgrp + "\n\t" + plock) return 1 else: iofun.out(self.label + " unexpected direct message: " + msg.toString()) return 0 iofun.out(self.label + " = " + format(tmp, '02d')) return 1