class Device: name = "" address = InsteonAddress() db = None dbbuilder = None querier = None def __init__(self, name, addr): self.name = name self.address = addr self.db = DB() self.querier = Querier(addr) addDev(self) def modifyDB(self, listener): self.dbbuilder.setListener(listener) # after db download complete, listener will perform action self.getdb() def setRecord(self, offset, laddr, group, linkType, data): msg = self.makeMsg(offset, laddr, group, linkType,data) self.querier.setMsgHandler(MsgHandler("got set record")) self.querier.sendMsg(msg) def makeMsg(self, offset, laddr, group, linkType, data): msg = Msg.s_makeMessage("SendExtendedMessage") msg.setAddress("toAddress", InsteonAddress(self.getAddress())) msg.setByte("messageFlags", 0x1f) msg.setByte("command1", 0x2f) msg.setByte("command2", 0x00) msg.setByte("userData1", 0x00) # don't care info msg.setByte("userData2", 0x02) # set database msg.setByte("userData3", offset >> 8) # high byte msg.setByte("userData4", offset & 0xff) # low byte msg.setByte("userData5", 8) # number of bytes set: 1...8 msg.setByte("userData6", linkType) msg.setByte("userData7", group) msg.setByte("userData8", laddr.getHighByte()) msg.setByte("userData9", laddr.getMiddleByte()) msg.setByte("userData10", laddr.getLowByte()) # depends on mode: could be e.g. trigger point msg.setByte("userData11", data[0]) msg.setByte("userData12", data[1]) # unused? msg.setByte("userData13", data[2]) # unused? rb = msg.getBytes("command1", 15); checksum = (~sum(rb) + 1) & 0xFF msg.setByte("userData14", checksum) return msg def getName(self): return self.name def getAddress(self): return self.address 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 printdb(self): """printdb() print the downloaded link database to the console""" self.dbbuilder.printdb() def getId(self): """getId() get category, subcategory, firmware, hardware version""" self.querier.setMsgHandler(IdMsgHandler("id")) self.querier.querysd(0x10, 0x00) # # link database management # def addController(self, addr, group, data = None): """addController(addr, group[, data]) add device with "addr" as controller for group "group", with link data "data" """ data = data if data else [00, 00, group]; self.modifyDB(LinkRecordAdder(self, addr, group, data, True)) def removeController(self, addr, group): """removeController(addr, group) remove device with "addr" as controller for group "group", with link data "data" """ self.modifyDB(LinkRecordRemover(self, addr, group, True)) def addResponder(self, addr, group, data = None): """addResponder(addr, group[, data]) add device with "addr" as responder for group "group", with link data "data" """ data = data if data else [00, 00, group]; self.modifyDB(LinkRecordAdder(self, addr, group, data, False)) def removeResponder(self, addr, group): """removeResponder(addr, group) remove device with "addr" as responder for group "group" """ self.modifyDB(LinkRecordRemover(self, addr, group, False)) def removeDevice(self, addr): """removeDevice(addr): removes all links to device with address "addr" from device database""" self.modifyDB(DeviceRemover(self, addr)) def replaceDevice(self, oldAddr, newAddr): """replaceDevice(oldAddr, newAddr): replaces all linkdb occurrences of oldAddr with newAddr """ self.dbbuilder.setListener(AddressReplacer(self, oldAddr, newAddr)) # after db download is complete, listener will perform action self.getdb() def removeLastRecord(self): """removeLastRecord() removes the last device in the link database""" self.modifyDB(LastRecordRemover(self)) def nukeDB(self): """nukeDB() really WIPES OUT all records in the device's database!""" self.modifyDB(LastNRecordRemover(self, -1)) def setOnLevelResponder(self, addr, group, level, ramprate = 28, button = 1): """setOnLevelResponder(addr, group, level, ramprate = 28, button = 1) sets (on level, ramp rate, button) for controller with "addr" and group "group" """ self.modifyDB(OnLevelModifier(self, addr, group, level, ramprate, button, False)) def enterLinkingMode(self, group): """enterLinkingMode(group) causes the device to enter linking mode""" self.querier.setMsgHandler(MsgHandler("enter linking mode")) self.querier.querysd(0x09, group); def exitLinkingMode(self): """exitLinkingMode() causes the device to exit linking mode""" self.querier.setMsgHandler(MsgHandler("exit linking mode")) self.querier.querysd(0x08, 0x01); def enterUnlinkingMode(self, group): """enterUnlinkingMode(group) causes the device to enter unlinking mode""" self.querier.setMsgHandler(MsgHandler("enter unlinking mode")) self.querier.querysd(0x0A, group);
class Modem2413U(Device): """============== Insteon PowerLinc modem (PLM) ===============""" def __init__(self, name, addr): Device.__init__(self, name, addr) self.dbbuilder = ModemDBBuilder(addr, self.db) 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 getdb(self): """getdb() download the modem database and print it on the console""" self.dbbuilder.start() self.dbbuilder.wait() self.dbbuilder.dumpDB() out("Modem Link DB complete") def readdb(self): """readdb() download the modem database and return it""" self.dbbuilder.start() self.dbbuilder.wait() out("Modem Link DB complete!") return self.dbbuilder.getdb() def startWatch(self): """startWatch() modem will print all incoming messages on terminal""" self.querier = Querier(InsteonAddress("00.00.00")) self.querier.setMsgHandler(MsgDumper("modem")) self.querier.startWait(10000) def stopWatch(self): """stopWatch() stop modem from printing all incoming messages on terminal""" if (self.querier): self.querier.cancel() def getid(self): """getid() get modem id data""" self.querier = Querier(InsteonAddress("00.00.00")) self.querier.setMsgHandler(IMInfoMsgHandler("getid")) msg = Msg.s_makeMessage("GetIMInfo") self.querier.sendMsg(msg) def getIMConfig(self): """getIMConfig() get modem configuration flags byte""" self.querier = Querier(InsteonAddress("00.00.00")) self.querier.setMsgHandler(IMConfigMsgHandler("getIMConfig")) msg = Msg.s_makeMessage("GetIMConfig") self.querier.sendMsg(msg) def sendOn(self, group): """sendOn(group) sends ALLLink broadcast ON message to group "group" """ msg = message.createStdMsg(InsteonAddress("00.00.00"), 0x0f, 0x11, 0xFF, group) iofun.writeMsg(msg) iofun.out("sent msg: " + msg.toString()) 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 linkAsController(self, group): """linkAsController(group) puts modem in link mode on group "group" """ self.querier.setMsgHandler(DefaultMsgHandler("link as controller")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0x01) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def linkAsResponder(self, group): """linkAsResponder(group) puts modem in link mode on group "group" """ self.querier.setMsgHandler(DefaultMsgHandler("start linking")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0x00) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def linkAsEither(self, group): """linkAsEither(group) puts modem in link mode to link as controller or responder on group "group" """ self.querier.setMsgHandler( DefaultMsgHandler("link/unlink as controller or responder")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0x03) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def respondToUnlink(self, group): """respondToUnlink(group) make modem respond to unlink message""" # could not get 0xFF to unlink self.linkAsEither(group) def unlinkAsController(self, group): """unlinkAsController(group) puts modem in unlink mode to unlink as controller on group "group" """ self.querier.setMsgHandler(DefaultMsgHandler("unlink as controller")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0xFF) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def cancelLinking(self): """cancelLinking() takes modem out of linking or unlinking mode""" self.querier.setMsgHandler(DefaultMsgHandler("cancel linking")) msg = Msg.s_makeMessage("CancelALLLinking") self.querier.sendMsg(msg) def addController(self, addr, group): """addController(addr, group): adds device with address "addr" to modem link database as controller for group "group" """ self.modifyRecord(addr, group, 0x40, 0xa2, [0, 0, group], "addController") def addResponder(self, addr, group, data=None): """addResponder(addr, group[, data]): adds device with address "addr" to modem link database as responder to group "group" """ data = data if data else [00, 00, group] self.modifyRecord(addr, group, 0x41, 0xa2, data, "addResponder") def addSoftwareResponder(self, addr): """addSoftwareResponder(addr): adds device with address "addr" to modem link database as software responder""" self.modifyRecord(addr, 0xef, 0x41, 0xa2, [0, 0, 0xef], "addSoftwareController") def removeResponderOrController(self, addr, group): """removeResponderOrController(addr, group) removes device with address "addr" and group "group" from modem link database""" self.__deleteFirstRecord(addr, group, "removeResponderOrController") def removeResponder(self, addr, group): """removeResponder(addr, group) could not be implemented for the modem. Use removeResponderOrController() instead!""" iofun.out("removeResponder(addr, group) could not be implemented" + " for the modem. Use removeResponderOrController() instead!") 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 removeDevice(self, addr): """removeDevice(addr): removes all links to device with address "addr" from modem database""" self.__modifyModemDB(DeviceRemover(self, addr)) def __deleteFirstRecord(self, addr, group, text="delete record"): self.modifyRecord(addr, group, 0x80, 0x00, [0, 0, 0], text) def modifyFirstOrAdd(self, addr, group, recordFlags, data): if (recordFlags & (1 << 6)): # controller self.modifyRecord(addr, group, 0x40, recordFlags, data, "modify first or add") else: self.modifyRecord(addr, group, 0x41, recordFlags, data, "modify first or add") def modifyFirstControllerOrAdd(self, addr, group, data): self.modifyRecord(addr, group, 0x40, 0xe2, data, "modify first ctrl found or add") def modifyFirstResponderOrAdd(self, addr, group, data): self.modifyRecord(addr, group, 0x41, 0xa2, data, "modify first resp found or add") def modifyRecord(self, addr, group, controlCode, recordFlags, data, txt): msg = self.__makeModMsg(addr, group, controlCode, recordFlags, data, txt) self.querier = Querier(self.address) self.querier.setMsgHandler(DefaultMsgHandler(txt)) self.querier.sendMsg(msg) def __makeModMsg(self, addr, group, controlCode, recordFlags, data, txt): msg = Msg.s_makeMessage("ManageALLLinkRecord") msg.setByte("controlCode", controlCode) # mod. first ctrl found or add msg.setByte("recordFlags", recordFlags) msg.setByte("ALLLinkGroup", group) msg.setAddress("linkAddress", InsteonAddress(addr)) msg.setByte("linkData1", data[0] & 0xFF) msg.setByte("linkData2", data[1] & 0xFF) msg.setByte("linkData3", data[2] & 0xFF) return msg def saveDB(self, filename): """saveDB(filename) save modem database to file "filename" """ self.dbbuilder.start() self.dbbuilder.wait() self.dbbuilder.saveDB(filename) def loadDB(self, filename): """loadDB(filename) load modem database from file "filename" (note: this will not change the actual modem db) """ self.dbbuilder.loadDB(filename) self.dbbuilder.dumpDB() def nukeDB(self): """nukeDB() delete complete modem database! """ self.dbbuilder.start() self.dbbuilder.wait() self.dbbuilder.nukeDB(self) def restoreDB(self, filename): """restoreDB(filename) restore modem database from file "filename" """ self.loadDB(filename) self.dbbuilder.restoreDB(self, filename)
class Device: name = "" address = InsteonAddress() db = None dbbuilder = None querier = None def __init__(self, name, addr): self.name = name self.address = addr self.db = DB() self.querier = Querier(addr) addDev(self) def modifyDB(self, listener): self.dbbuilder.setListener(listener) # after db download complete, listener will perform action self.getdb() def setRecord(self, offset, laddr, group, linkType, data): msg = self.makeMsg(offset, laddr, group, linkType,data) self.querier.setMsgHandler(MsgHandler("got set record")) self.querier.sendMsg(msg) def makeMsg(self, offset, laddr, group, linkType, data): msg = Msg.s_makeMessage("SendExtendedMessage") msg.setAddress("toAddress", InsteonAddress(self.getAddress())) msg.setByte("messageFlags", 0x1f) msg.setByte("command1", 0x2f) msg.setByte("command2", 0x00) msg.setByte("userData1", 0x00) # don't care info msg.setByte("userData2", 0x02) # set database msg.setByte("userData3", offset >> 8) # high byte msg.setByte("userData4", offset & 0xff) # low byte msg.setByte("userData5", 8) # number of bytes set: 1...8 msg.setByte("userData6", linkType) msg.setByte("userData7", group) msg.setByte("userData8", laddr.getHighByte()) msg.setByte("userData9", laddr.getMiddleByte()) msg.setByte("userData10", laddr.getLowByte()) # depends on mode: could be e.g. trigger point msg.setByte("userData11", data[0]) msg.setByte("userData12", data[1]) # unused? msg.setByte("userData13", data[2]) # unused? rb = msg.getBytes("command1", 15); checksum = (~sum(rb) + 1) & 0xFF msg.setByte("userData14", checksum) return msg def getName(self): return self.name def getAddress(self): return self.address 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 printdb(self): """printdb() print the downloaded link database to the console""" self.dbbuilder.printdb() def getId(self): """getId() get category, subcategory, firmware, hardware version""" self.querier.setMsgHandler(IdMsgHandler("id")) self.querier.querysd(0x10, 0x00) # # link database management # def addController(self, addr, group, data = None): """addController(addr, group, data) add device with "addr" as controller for group "group", with link data "data" """ data = data if data else [00, 00, group]; self.modifyDB(LinkRecordAdder(self, addr, group, data, True)) def removeController(self, addr, group): """removeController(addr, group) remove device with "addr" as controller for group "group", with link data "data" """ self.modifyDB(LinkRecordRemover(self, addr, group, True)) def addResponder(self, addr, group, data = None): """addResponder(addr, group, data) add device with "addr" as responder for group "group", with link data "data" """ data = data if data else [00, 00, group]; self.modifyDB(LinkRecordAdder(self, addr, group, data, False)) def removeResponder(self, addr, group): """removeResponder(addr, group) remove device with "addr" as responder for group "group" """ self.modifyDB(LinkRecordRemover(self, addr, group, False)) def removeDevice(self, addr): """removeDevice(addr): removes all links to device with address "addr" from device database""" self.modifyDB(DeviceRemover(self, addr)) def replaceDevice(self, oldAddr, newAddr): """replaceDevice(oldAddr, newAddr): replaces all linkdb occurrences of oldAddr with newAddr """ self.dbbuilder.setListener(AddressReplacer(self, oldAddr, newAddr)) # after db download is complete, listener will perform action self.getdb() def removeLastRecord(self): """removeLastRecord() removes the last device in the link database""" self.modifyDB(LastRecordRemover(self)) def nukeDB(self): """nukeDB() really WIPES OUT all records in the device's database!""" self.modifyDB(LastNRecordRemover(self, -1)) def setOnLevelResponder(self, addr, group, level, ramprate = 28, button = 1): """setOnLevelResponder(addr, group, level, ramprate = 28, button = 1) sets (on level, ramp rate, button) for controller with "addr" and group "group" """ self.modifyDB(OnLevelModifier(self, addr, group, level, ramprate, button, False))
class Modem2413U(Device): """============== Insteon PowerLinc modem (PLM) ===============""" def __init__(self, name, addr): Device.__init__(self, name, addr) self.dbbuilder = ModemDBBuilder(addr, self.db) 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 getdb(self): """getdb() download the modem database and print it on the console""" self.dbbuilder.start() self.dbbuilder.wait() self.dbbuilder.dumpDB() out("Modem Link DB complete") def startWatch(self): """startWatch() modem will print all incoming messages on terminal""" self.querier = Querier(InsteonAddress("00.00.00")) self.querier.setMsgHandler(MsgDumper("modem")) self.querier.startWait(10000) def stopWatch(self): """stopWatch() stop modem from printing all incoming messages on terminal""" if (self.querier): self.querier.cancel() def getid(self): """getid() get modem id data""" self.querier = Querier(InsteonAddress("00.00.00")) self.querier.setMsgHandler(IMInfoMsgHandler("getid")) msg = Msg.s_makeMessage("GetIMInfo") self.querier.sendMsg(msg) def sendOn(self, group): """sendOn(group) sends ALLLink broadcast ON message to group "group" """ msg = message.createStdMsg(InsteonAddress("00.00.00"), 0x0f, 0x11, 0xFF, group) iofun.writeMsg(msg) iofun.out("sent msg: " + msg.toString()) 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 linkAsController(self, otherDevice, group): """linkAsController(otherDevice, group) puts modem in link mode to control device "otherDevice" on group "group" """ addr = InsteonAddress(otherDevice) self.querier = Querier(addr) self.querier.setMsgHandler(DefaultMsgHandler("link as controller")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0x01) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def linkAsResponder(self, otherDevice, group): """linkAsResponder(otherDevice, group) puts modem in link mode to respond to device "otherDevice" on group "group" """ addr = InsteonAddress(otherDevice) self.querier = Querier(addr) self.querier.setMsgHandler(DefaultMsgHandler("start linking")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0x00) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def linkAsEither(self, otherDevice, group): """linkAsEither(otherDevice, group) puts modem in link mode to link as controller or responder to device "otherDevice" on group "group" """ addr = InsteonAddress(otherDevice) self.querier = Querier(addr) self.querier.setMsgHandler( DefaultMsgHandler("link/unlink as controller or responder")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0x03) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def respondToUnlink(self, otherDevice, group): """respondToUnlink(otherDevice, group) make modem respond to unlink message from other device""" # could not get 0xFF to unlink self.linkAsEither(otherDevice, group) def unlinkAsController(self, otherDevice, group): """unlinkAsController(otherDevice, group) puts modem in unlink mode to unlink as controller from device "otherDevice" on group "group" """ addr = InsteonAddress(otherDevice) self.querier = Querier(addr) self.querier.setMsgHandler(DefaultMsgHandler("unlink as controller")) msg = Msg.s_makeMessage("StartALLLinking") msg.setByte("LinkCode", 0xFF) msg.setByte("ALLLinkGroup", group) self.querier.sendMsg(msg) def cancelLinking(self): """cancelLinking() takes modem out of linking or unlinking mode""" self.querier = Querier(InsteonAddress("00.00.00")) self.querier.setMsgHandler(DefaultMsgHandler("cancel linking")) msg = Msg.s_makeMessage("CancelALLLinking") self.querier.sendMsg(msg) def addController(self, addr, group): """addController(addr, group): adds device with address "addr" to modem link database as controller for group "group" """ self.modifyRecord(addr, group, 0x40, 0xa2, [0,0,group], "addController") def addResponder(self, addr, group): """addResponder(addr, group): adds device with address "addr" to modem link database as responder to group "group" """ self.modifyRecord(addr, group, 0x41, 0xa2, [0,0,group], "addResponder") def addSoftwareResponder(self, addr): """addSoftwareResponder(addr): adds device with address "addr" to modem link database as software responder""" self.modifyRecord(addr, 0xef, 0x41, 0xa2, [0,0,0xef], "addSoftwareController") def removeResponderOrController(self, addr, group): """removeResponderOrController(addr, group) removes device with address "addr" and group "group" from modem link database""" self.__deleteFirstRecord(addr, group, "removeResponderOrController") def removeResponder(self, addr, group): """removeResponder(addr, group) could not be implemented for the modem. Use removeResponderOrController() instead!""" iofun.out("removeResponder(addr, group) could not be implemented" + " for the modem. Use removeResponderOrController() instead!") 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 removeDevice(self, addr): """removeDevice(addr): removes all links to device with address "addr" from modem database""" self.__modifyModemDB(DeviceRemover(self, addr)) def __deleteFirstRecord(self, addr, group, text = "delete record"): self.modifyRecord(addr, group, 0x80, 0x00, [0,0,0], text) def modifyFirstOrAdd(self, addr, group, recordFlags, data): if (recordFlags & (1 << 6)): # controller self.modifyRecord(addr, group, 0x40, recordFlags, data, "modify first or add") else: self.modifyRecord(addr, group, 0x41, recordFlags, data, "modify first or add") def modifyFirstControllerOrAdd(self, addr, group, data): self.modifyRecord(addr, group, 0x40, 0xe2, data, "modify first ctrl found or add") def modifyFirstResponderOrAdd(self, addr, group, data): self.modifyRecord(addr, group, 0x41, 0xa2, data, "modify first resp found or add") def modifyRecord(self, addr, group, controlCode, recordFlags, data, txt): msg = self.__makeModMsg(addr, group, controlCode, recordFlags, data, txt) self.querier = Querier(self.address) self.querier.setMsgHandler(DefaultMsgHandler(txt)) self.querier.sendMsg(msg) def __makeModMsg(self, addr, group, controlCode, recordFlags, data, txt): msg = Msg.s_makeMessage("ManageALLLinkRecord"); msg.setByte("controlCode", controlCode); # mod. first ctrl found or add msg.setByte("recordFlags", recordFlags); msg.setByte("ALLLinkGroup", group); msg.setAddress("linkAddress", InsteonAddress(addr)); msg.setByte("linkData1", data[0] & 0xFF) msg.setByte("linkData2", data[1] & 0xFF) msg.setByte("linkData3", data[2] & 0xFF) return msg; def saveDB(self, filename): """saveDB(filename) save modem database to file "filename" """ self.dbbuilder.start() self.dbbuilder.wait() self.dbbuilder.saveDB(filename) def loadDB(self, filename): """loadDB(filename) restore modem database from file "filename" """ self.dbbuilder.loadDB(filename) self.dbbuilder.dumpDB() def nukeDB(self): """nukeDB() delete complete modem database! """ self.dbbuilder.start() self.dbbuilder.wait() self.dbbuilder.nukeDB(self) def restoreDB(self, filename): """restoreDB() restore modem database from file "filename" """ self.loadDB(filename) self.dbbuilder.restoreDB(self, filename)