def getLogEntriesCount(self, pinHex): self._makeBLEConnection() keyturnerUSDIOHandle = self.device.get_handle("a92ee202-5501-11e4-916c-0800200c9a66") self.device.subscribe('a92ee202-5501-11e4-916c-0800200c9a66', self._handleCharWriteResponse, indication=True)) challengeReq = nuki_messages.Nuki_REQ('0004') challengeReqEncrypted = nuki_messages.Nuki_EncryptedCommand(authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=challengeReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) challengeReqEncryptedCommand = challengeReqEncrypted.generate() self._charWriteResponse = "" print "Requesting CHALLENGE: %s" % challengeReqEncrypted.generate("HEX") self.device.char_write_handle(keyturnerUSDIOHandle,challengeReqEncryptedCommand,True,5) print "Nuki CHALLENGE Request sent: %s" % challengeReq.show() time.sleep(2) commandParsed = self.parser.decrypt(self._charWriteResponse,self.config.get(self.macAddress, 'publicKeyNuki'),self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki CHALLENGE: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if commandParsed.command != '0004': sys.exit("Nuki returned unexpected response (expecting Nuki CHALLENGE): %s" % commandParsed.show()) print "Challenge received: %s" % commandParsed.nonce logEntriesReq = nuki_messages.Nuki_LOG_ENTRIES_REQUEST() logEntriesReq.createPayload(0, commandParsed.nonce, self.byteSwapper.swap(pinHex)) logEntriesReqEncrypted = nuki_messages.Nuki_EncryptedCommand(authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=logEntriesReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) logEntriesReqEncryptedCommand = logEntriesReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle,logEntriesReqEncryptedCommand,True,4) print "Nuki Log Entries Request sent: %s" % logEntriesReq.show() time.sleep(2) commandParsed = self.parser.decrypt(self._charWriteResponse,self.config.get(self.macAddress, 'publicKeyNuki'),self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki Log Entries: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if commandParsed.command != '0026': sys.exit("Nuki returned unexpected response (expecting Nuki LOG ENTRY): %s" % commandParsed.show()) print "%s" % commandParsed.show() return int(commandParsed.logCount, 16)
def readLockState(self): self._makeBLEConnection() keyturnerUSDIOHandle = self.device.get_handle( "a92ee202-5501-11e4-916c-0800200c9a66") self.device.subscribe('a92ee202-5501-11e4-916c-0800200c9a66', self._handleCharWriteResponse) stateReq = nuki_messages.Nuki_REQ('000C') stateReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=stateReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) stateReqEncryptedCommand = stateReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle, stateReqEncryptedCommand, True, 3) print "Nuki State Request sent: %s\nresponse received: %s" % ( stateReq.show(), self._charWriteResponse) commandParsed = self.parser.decrypt( self._charWriteResponse, self.config.get(self.macAddress, 'publicKeyNuki'), self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki STATES: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if commandParsed.command != '000C': sys.exit( "Nuki returned unexpected response (expecting Nuki STATES): %s" % commandParsed.show()) print "%s" % commandParsed.show() return commandParsed
def lockAction(self,lockAction): self._makeBLEConnection() keyturnerUSDIOHandle = self.device.get_handle("a92ee202-5501-11e4-916c-0800200c9a66") self.device.subscribe('a92ee202-5501-11e4-916c-0800200c9a66', self._handleCharWriteResponse, indication=True)) challengeReq = nuki_messages.Nuki_REQ('0004') challengeReqEncrypted = nuki_messages.Nuki_EncryptedCommand(authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=challengeReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) challengeReqEncryptedCommand = challengeReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle,challengeReqEncryptedCommand,True,4) print "Nuki CHALLENGE Request sent: %s" % challengeReq.show() time.sleep(2) commandParsed = self.parser.decrypt(self._charWriteResponse,self.config.get(self.macAddress, 'publicKeyNuki'),self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki CHALLENGE: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if commandParsed.command != '0004': sys.exit("Nuki returned unexpected response (expecting Nuki CHALLENGE): %s" % commandParsed.show()) print "Challenge received: %s" % commandParsed.nonce lockActionReq = nuki_messages.Nuki_LOCK_ACTION() lockActionReq.createPayload(self.config.getint(self.macAddress, 'ID'), lockAction, commandParsed.nonce) lockActionReqEncrypted = nuki_messages.Nuki_EncryptedCommand(authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=lockActionReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) lockActionReqEncryptedCommand = lockActionReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle,lockActionReqEncryptedCommand,True,4) print "Nuki Lock Action Request sent: %s" % lockActionReq.show() time.sleep(2) commandParsed = self.parser.decrypt(self._charWriteResponse,self.config.get(self.macAddress, 'publicKeyNuki'),self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki Lock Action: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if commandParsed.command != '000C' and commandParsed.command != '000E': sys.exit("Nuki returned unexpected response (expecting Nuki STATUS/STATES): %s" % commandParsed.show()) print "%s" % commandParsed.show()
def executeChallenge(self, request, keyturnerUSDIOHandle): print("Going to execute challenge") challengeReq = nuki_messages.Nuki_REQ(request) challengeReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=challengeReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) challengeReqEncryptedCommand = challengeReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle, challengeReqEncryptedCommand, True, 4) print("Nuki CHALLENGE Request sent: %s" % challengeReq.show())
def authenticateUser(self, publicKeyHex, privateKeyHex, ID, IDType, name): self._makeBLEConnection() self.config.remove_section(self.macAddress) self.config.add_section(self.macAddress) pairingHandle = self.device.get_handle('a92ee101-5501-11e4-916c-0800200c9a66') print "Nuki Pairing UUID handle created: %04x" % pairingHandle publicKeyReq = nuki_messages.Nuki_REQ('0003') self.device.subscribe('a92ee101-5501-11e4-916c-0800200c9a66', self._handleCharWriteResponse, indication=True)) publicKeyReqCommand = publicKeyReq.generate() self._charWriteResponse = "" print "Requesting Nuki Public Key using command: %s" % publicKeyReq.show() self.device.char_write_handle(pairingHandle,publicKeyReqCommand,True,2) print "Nuki Public key requested" time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit("Error while requesting public key: %s" % commandParsed) if commandParsed.command != '0003': sys.exit("Nuki returned unexpected response (expecting PUBLIC_KEY): %s" % commandParsed.show()) publicKeyNuki = commandParsed.publicKey self.config.set(self.macAddress,'publicKeyNuki',publicKeyNuki) self.config.set(self.macAddress,'publicKeyHex',publicKeyHex) self.config.set(self.macAddress,'privateKeyHex',privateKeyHex) self.config.set(self.macAddress,'ID',ID) self.config.set(self.macAddress,'IDType',IDType) self.config.set(self.macAddress,'Name',name) print "Public key received: %s" % commandParsed.publicKey publicKeyPush = nuki_messages.Nuki_PUBLIC_KEY(publicKeyHex) publicKeyPushCommand = publicKeyPush.generate() print "Pushing Public Key using command: %s" % publicKeyPush.show() self._charWriteResponse = "" self.device.char_write_handle(pairingHandle,publicKeyPushCommand,True,5) print "Public key pushed" time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit("Error while pushing public key: %s" % commandParsed) if commandParsed.command != '0004': sys.exit("Nuki returned unexpected response (expecting CHALLENGE): %s" % commandParsed.show()) print "Challenge received: %s" % commandParsed.nonce nonceNuki = commandParsed.nonce authAuthenticator = nuki_messages.Nuki_AUTH_AUTHENTICATOR() authAuthenticator.createPayload(nonceNuki, privateKeyHex, publicKeyHex, publicKeyNuki) authAuthenticatorCommand = authAuthenticator.generate() self._charWriteResponse = "" self.device.char_write_handle(pairingHandle,authAuthenticatorCommand,True,5) print "Authorization Authenticator sent: %s" % authAuthenticator.show() time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit("Error while sending Authorization Authenticator: %s" % commandParsed) if commandParsed.command != '0004': sys.exit("Nuki returned unexpected response (expecting CHALLENGE): %s" % commandParsed.show()) print "Challenge received: %s" % commandParsed.nonce nonceNuki = commandParsed.nonce authData = nuki_messages.Nuki_AUTH_DATA() authData.createPayload(publicKeyNuki, privateKeyHex, publicKeyHex, nonceNuki, ID, IDType, name) authDataCommand = authData.generate() self._charWriteResponse = "" self.device.char_write_handle(pairingHandle,authDataCommand,True,7) print "Authorization Data sent: %s" % authData.show() time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit("Error while sending Authorization Data: %s" % commandParsed) if commandParsed.command != '0007': sys.exit("Nuki returned unexpected response (expecting AUTH_ID): %s" % commandParsed.show()) print "Authorization ID received: %s" % commandParsed.show() nonceNuki = commandParsed.nonce authorizationID = commandParsed.authID self.config.set(self.macAddress,'authorizationID',authorizationID) authId = int(commandParsed.authID,16) authIDConfirm = nuki_messages.Nuki_AUTH_ID_CONFIRM() authIDConfirm.createPayload(publicKeyNuki, privateKeyHex, publicKeyHex, nonceNuki, authId) authIDConfirmCommand = authIDConfirm.generate() self._charWriteResponse = "" self.device.char_write_handle(pairingHandle,authIDConfirmCommand,True,7) print "Authorization ID Confirmation sent: %s" % authIDConfirm.show() time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit("Error while sending Authorization ID Confirmation: %s" % commandParsed) if commandParsed.command != '000E': sys.exit("Nuki returned unexpected response (expecting STATUS): %s" % commandParsed.show()) print "STATUS received: %s" % commandParsed.status with open('/home/pi/nuki/nuki.cfg', 'wb') as configfile: self.config.write(configfile) return commandParsed.status
def getLogEntries(self, count, pinHex): self._makeBLEConnection() keyturnerUSDIOHandle = self.device.get_handle( "a92ee202-5501-11e4-916c-0800200c9a66") self.device.subscribe('a92ee202-5501-11e4-916c-0800200c9a66', self._handleCharWriteResponse) challengeReq = nuki_messages.Nuki_REQ('0004') challengeReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=challengeReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) challengeReqEncryptedCommand = challengeReqEncrypted.generate() print "Requesting CHALLENGE: %s" % challengeReqEncrypted.generate( "HEX") self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle, challengeReqEncryptedCommand, True, 5) print "Nuki CHALLENGE Request sent: %s" % challengeReq.show() commandParsed = self.parser.decrypt( self._charWriteResponse, self.config.get(self.macAddress, 'publicKeyNuki'), self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki CHALLENGE: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if commandParsed.command != '0004': sys.exit( "Nuki returned unexpected response (expecting Nuki CHALLENGE): %s" % commandParsed.show()) print "Challenge received: %s" % commandParsed.nonce logEntriesReq = nuki_messages.Nuki_LOG_ENTRIES_REQUEST() logEntriesReq.createPayload(count, commandParsed.nonce, self.byteSwapper.swap(pinHex)) logEntriesReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=logEntriesReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) logEntriesReqEncryptedCommand = logEntriesReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle, logEntriesReqEncryptedCommand, True, 6) print "Nuki Log Entries Request sent: %s" % logEntriesReq.show() messages = self.parser.splitEncryptedMessages(self._charWriteResponse) print "Received %d messages" % len(messages) logMessages = [] for message in messages: print "Decrypting message %s" % message try: commandParsed = self.parser.decrypt( message, self.config.get(self.macAddress, 'publicKeyNuki'), self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki Log Entries: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if commandParsed.command != '0024' and commandParsed.command != '0026' and commandParsed.command != '000E': sys.exit( "Nuki returned unexpected response (expecting Nuki LOG ENTRY): %s" % commandParsed.show()) print "%s" % commandParsed.show() if commandParsed.command == '0024': logMessages.append(commandParsed) except: print "Unable to decrypt message" return logMessages
def getLogEntries(self, count, pinHex): self._makeBLEConnection() keyturnerUSDIOHandle = self.device.get_handle(DEVICE_HANDLEID2) self.device.subscribe(DEVICE_HANDLEID2, self._handleCharWriteResponse, indication=True) challengeReq = nuki_messages.Nuki_REQ( nuki_messages.Nuki_CHALLENGE.command) challengeReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=challengeReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) challengeReqEncryptedCommand = challengeReqEncrypted.generate() print(f"Requesting CHALLENGE: {challengeReqEncrypted.generate('HEX')}") self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle, challengeReqEncryptedCommand, True, 5) print("Nuki CHALLENGE Request sent: %s" % challengeReq.show()) # time.sleep(2) commandParsed = self.parser.decrypt( self._charWriteResponse, self.config.get(self.macAddress, 'publicKeyNuki'), self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit("Error while requesting Nuki CHALLENGE: %s" % commandParsed) commandParsed = self.parser.parse(commandParsed) if type(commandParsed) != nuki_messages.Nuki_CHALLENGE: sys.exit( "Nuki returned unexpected response (expecting Nuki CHALLENGE): %s" % commandParsed.show()) print("Challenge received: %s" % commandParsed.nonce) logEntriesReq = nuki_messages.Nuki_LOG_ENTRIES_REQUEST() logEntriesReq.createPayload(count, commandParsed.nonce, self.byteSwapper.swap(pinHex)) logEntriesReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=logEntriesReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) logEntriesReqEncryptedCommand = logEntriesReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle, logEntriesReqEncryptedCommand, True, 6) print("Nuki Log Entries Request sent: %s" % logEntriesReq.show()) # time.sleep(2) messages = self.parser.splitEncryptedMessages(self._charWriteResponse) print("Received %d messages" % len(messages)) logMessages = [] for message in messages: print(f"Decrypting message {message}") try: commandParsed = self.parser.decrypt( message, self.config.get(self.macAddress, 'publicKeyNuki'), self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit( f"Error while requesting Nuki Log Entries: {commandParsed}" ) commandParsed = self.parser.parse(commandParsed) if type(commandParsed) not in [ nuki_messages.Nuki_LOG_ENTRY, nuki_messages.Nuki_LOG_ENTRY_COUNT, nuki_messages.Nuki_STATUS ]: sys.exit( "Nuki returned unexpected response (expecting Nuki LOG ENTRY): %s" % commandParsed.show()) print("%s" % commandParsed.show()) if type(commandParsed) == nuki_messages.Nuki_LOG_ENTRY: logMessages.append(commandParsed) except: print("Unable to decrypt message") return logMessages
def getLogEntriesCount(self, pinHex): self._makeBLEConnection() keyturnerUSDIOHandle = self.device.get_handle(DEVICE_HANDLEID2) self.device.subscribe(DEVICE_HANDLEID2, self._handleCharWriteResponse, indication=True) challengeReq = nuki_messages.Nuki_REQ( nuki_messages.Nuki_CHALLENGE.command) challengeReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=challengeReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex')) challengeReqEncryptedCommand = challengeReqEncrypted.generate() self._charWriteResponse = "" print(f"Requesting CHALLENGE: {challengeReqEncrypted.generate('HEX')}") self.device.char_write_handle(keyturnerUSDIOHandle, challengeReqEncryptedCommand, True, 5) print("Nuki CHALLENGE Request sent: %s" % challengeReq.show()) # time.sleep(2) commandParsed = self.parser.decrypt( self._charWriteResponse, self.config.get(self.macAddress, 'publicKeyNuki'), self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit(f"Error while requesting Nuki CHALLENGE: {commandParsed}") commandParsed = self.parser.parse(commandParsed) if type(commandParsed) != nuki_messages.Nuki_CHALLENGE: sys.exit( f"Nuki returned unexpected response (expecting Nuki CHALLENGE): {commandParsed.show()}" ) print(f"Challenge received: {commandParsed.nonce}") logEntriesReq = nuki_messages.Nuki_LOG_ENTRIES_REQUEST() logEntriesReq.createPayload(0, commandParsed.nonce, self.byteSwapper.swap(pinHex)) logEntriesReqEncrypted = nuki_messages.Nuki_EncryptedCommand( authID=self.config.get(self.macAddress, 'authorizationID'), nukiCommand=logEntriesReq, publicKey=self.config.get(self.macAddress, 'publicKeyNuki'), privateKey=self.config.get(self.macAddress, 'privateKeyHex'), ) logEntriesReqEncryptedCommand = logEntriesReqEncrypted.generate() self._charWriteResponse = "" self.device.char_write_handle(keyturnerUSDIOHandle, logEntriesReqEncryptedCommand, True, 4) print(f"Nuki Log Entries Request sent: {logEntriesReq.show()}") # time.sleep(2) commandParsed = self.parser.decrypt( self._charWriteResponse, self.config.get(self.macAddress, 'publicKeyNuki'), self.config.get(self.macAddress, 'privateKeyHex'))[8:] if self.parser.isNukiCommand(commandParsed) == False: sys.exit( f"Error while requesting Nuki Log Entries: {commandParsed}") commandParsed = self.parser.parse(commandParsed) if type(commandParsed) != nuki_messages.Nuki_LOG_ENTRY_COUNT: sys.exit( f"Nuki returned unexpected response (expecting Nuki LOG ENTRY): {commandParsed.show()}" ) print("%s" % commandParsed.show()) return int(commandParsed.logCount, 16)
def authenticateUser(self, publicKey, privateKeyHex, ID, IDType, name): self._makeBLEConnection() if self.device == None: return self.config.remove_section(self.macAddress) self.config.add_section(self.macAddress) pairingHandle = self.device.get_handle(DEVICE_HANDLEID1) print("Nuki Pairing UUID handle created: %04x" % pairingHandle) publicKeyReq = nuki_messages.Nuki_REQ( nuki_messages.Nuki_PUBLIC_KEY.command) self.device.subscribe(DEVICE_HANDLEID1, self._handleCharWriteResponse, indication=True) publicKeyReqCommand = publicKeyReq.generate() self._charWriteResponse = "" print( f"Requesting Nuki Public Key using command: {publicKeyReq.show()}") self.device.char_write_handle(pairingHandle, publicKeyReqCommand, True, 2) print("Nuki Public key requested") # wtf time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit(f"Error while requesting public key: {commandParsed}") if type(commandParsed) != nuki_messages.Nuki_PUBLIC_KEY: sys.exit( f"Nuki returned unexpected response (expecting PUBLIC_KEY): {commandParsed.show()}" ) publicKeyNuki = commandParsed.publicKey self.config.set(self.macAddress, 'publicKeyNuki', publicKeyNuki) self.config.set(self.macAddress, 'publicKeyHex', publicKey.hex()) self.config.set(self.macAddress, 'privateKeyHex', privateKeyHex) self.config.set(self.macAddress, 'ID', ID) self.config.set(self.macAddress, 'IDType', IDType) self.config.set(self.macAddress, 'Name', name) print(f"Public key received: {commandParsed.publicKey}") publicKeyPush = nuki_messages.Nuki_PUBLIC_KEY(publicKey) publicKeyPushCommand = publicKeyPush.generate() print(f"Pushing Public Key using command: {publicKeyPush.show()}") self._charWriteResponse = "" self.device.char_write_handle(pairingHandle, publicKeyPushCommand, True, 5) print("Public key pushed") time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit(f"Error while pushing public key: {commandParsed}") if type(commandParsed) != nuki_messages.Nuki_CHALLENGE: sys.exit( f"Nuki returned unexpected response (expecting CHALLENGE): {commandParsed.show()}" ) print(f"Challenge received: {commandParsed.nonce}") nonceNuki = commandParsed.nonce authAuthenticator = nuki_messages.Nuki_AUTH_AUTHENTICATOR() authAuthenticator.createPayload(nonceNuki, privateKeyHex, publicKey, publicKeyNuki) authAuthenticatorCommand = authAuthenticator.generate() self._charWriteResponse = "" self.device.char_write_handle(pairingHandle, authAuthenticatorCommand, True, 5) print(f"Authorization Authenticator sent: {authAuthenticator.show()}") time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit( f"Error while sending Authorization Authenticator: {commandParsed}" ) if type(commandParsed) != nuki_messages.Nuki_CHALLENGE: sys.exit( f"Nuki returned unexpected response (expecting CHALLENGE): {commandParsed.show()}" ) print(f"Challenge received: {commandParsed.nonce}") nonceNuki = commandParsed.nonce authData = nuki_messages.Nuki_AUTH_DATA() authData.createPayload(publicKeyNuki, privateKeyHex, nonceNuki, ID, IDType, name) authDataCommand = authData.generate() self._charWriteResponse = "" self.device.char_write_handle(pairingHandle, authDataCommand, True, 7) print(f"Authorization Data sent: {authData.show()}") time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit( f"Error while sending Authorization Data: {commandParsed}") if type(commandParsed) != nuki_messages.Nuki_AUTH_ID: sys.exit( f"Nuki returned unexpected response (expecting AUTH_ID): {commandParsed.show()}" ) print(f"Authorization ID received: {commandParsed.show()}") nonceNuki = commandParsed.nonce authorizationID = commandParsed.authID self.config.set(self.macAddress, 'authorizationID', authorizationID) authId = int(commandParsed.authID, 16) authIDConfirm = nuki_messages.Nuki_AUTH_ID_CONFIRM() authIDConfirm.createPayload(publicKeyNuki, privateKeyHex, nonceNuki, authId) authIDConfirmCommand = authIDConfirm.generate() self._charWriteResponse = "" self.device.char_write_handle(pairingHandle, authIDConfirmCommand, True, 7) print(f"Authorization ID Confirmation sent: {authIDConfirm.show()}") time.sleep(2) commandParsed = self.parser.parse(self._charWriteResponse) if self.parser.isNukiCommand(self._charWriteResponse) == False: sys.exit( f"Error while sending Authorization ID Confirmation: {commandParsed}" ) if commandParsed.command != '000E': sys.exit( f"Nuki returned unexpected response (expecting STATUS): {commandParsed.show()}" ) print(f"STATUS received: {commandParsed.status}") with open(self.configfile, 'w') as configfile: self.config.write(configfile) return commandParsed.status