diff --git a/examples/mqttdump.py b/examples/mqttdump.py
new file mode 100644
index 0000000..e60dc47
--- /dev/null
+++ b/examples/mqttdump.py
@@ -0,0 +1,269 @@
+#!/bin/python3
+
+# Mi365 Scooter Library
+# MiAuth - Authenticate and interact with Xiaomi devices over BLE
+# Copyright (C) 2021 Daljeet Nandha + modified by @catSIXe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+import sys
+import json
+import os
+import argparse
+import time
+from bluepy import btle
+
+from mim365mi.m365scooter import M365Scooter
+
+from message import *
+
+import struct
+
+parser = argparse.ArgumentParser()
+parser.add_argument("mac", help="mac address of target device")
+parser.add_argument("-c", "--command", help="send command (w/o checksum) to uart and print reply")
+parser.add_argument("-s", "--serial", action='store_true', help="retrieve serial number")
+parser.add_argument("-v", "--version", action='store_true', help="retrieve firmware version")
+parser.add_argument("-d", "--debug", action='store_true', help="activate debug log")
+
+parser.add_argument("-r", "--register", action='store_true',
+ help="register with device / create token (caution: will lose bond to all other apps)")
+parser.add_argument("-t", "--token_file", default="./mi_token",
+ help="path to mi token file (default: ./mi_token)")
+
+args = parser.parse_args()
+
+
+from miauth.mi.micrypto import MiCrypto
+
+from paho.mqtt import client as mqtt_client
+#broker = '65.108.182.254'
+port = 1883
+broker = '127.0.0.1'
+#port = 1880
+topic = "m365/test/"
+# generate client ID with pub prefix randomly
+client_id = f'john-xina'
+
+def connect_mqtt():
+ def on_connect(client, userdata, flags, rc):
+ if rc == 0:
+ print("Connected to MQTT Broker!")
+ else:
+ print("Failed to connect, return code %d\n", rc)
+
+ client = mqtt_client.Client(client_id)
+ client.username_pw_set('scooter', 'nigg2939294924958583')
+ client.on_connect = on_connect
+ client.connect(broker, port)
+ return client
+
+def main():
+ mqtt = connect_mqtt()
+ mc = M365Scooter(btle.Peripheral(), args.mac, debug=args.debug)
+
+ def lol(reg, payload):
+ payloadO = payload
+ payload = int.from_bytes(payload, signed=True, byteorder='little')
+
+ if reg == '23010d': #Motor phase A current
+ reg = 'esc_phase_a_current'
+ if reg == '23010e': #Motor phase B current
+ reg = 'esc_phase_b_current'
+ if reg == '23010f': #Motor phase C current
+ reg = 'esc_phase_c_current'
+ if reg == '230175': #drive mode
+ reg = 'drive_mode'
+ if reg == '230122': #batt percent
+ reg = 'bms_level'
+ if reg == '230150': #current
+ reg = 'esc_current_ma'
+ payload = payload * 10
+ if reg == '230148': #bms volt
+ reg = 'bms_volt'
+ payload = payload/1e2
+ if reg == '230147': #esc volt
+ reg = 'esc_volt'
+ payload = payload/1e2
+ if reg == '230126': #speed
+ reg = 'speed'
+
+ if reg == '230129': #Total mileage, m
+ reg = 'total_km'
+ payload = payload/1e3
+ if reg == '23012F': #Current mileage
+ reg = 'current_m'
+ if reg == '230132': #Total run time
+ reg = 'total_uptime'
+ if reg == '23013a': #triptime
+ reg = 'triptime1'
+
+ if reg == '23013e': #frame_temp
+ reg = 'frame_temp1'
+ payload = payload/1e1
+ if reg == '2301bb': #frame_temp
+ reg = 'frame_temp2'
+ payload = payload/1e1
+ if reg == '250140': # cell voltages
+ reg = 'bms_cell_voltages'
+ payload = []
+ for i in range(0, 10):
+ payload.append(int.from_bytes(payloadO[ (i*2) : (i*2)+2 ], signed=True, byteorder='little') /1e3)
+ payload = json.dumps(payload)
+ if reg == '25013b': # battery health
+ reg = 'bms_health'
+ if reg == '250130': # battery status
+ reg = 'bms_status'
+
+ if reg == '25011c': # Charge count
+ reg = 'bms_chargecount'
+ if reg == '25011b': # Charge full cycles
+ reg = 'bms_chargefullcount'
+ if reg == '250110': # Serial number
+ reg = 'bms_serial'
+ payload = payloadO.decode()
+ if reg == '250133': # bms current x10mA
+ reg = 'bms_current_ma'
+ payload = payload * 10
+ if reg == '250135': # bms temps high and low bytes, -20C offset
+ reg = 'bms_temp1'
+ payload = payloadO[ 1 ] - 20
+ mqtt.publish(topic + reg, payload)
+
+ reg = 'bms_temp2'
+ payload = payloadO[ 0 ] - 20
+ print(reg, payload)
+ mqtt.publish(topic + reg, payload)
+ mc.handleData(lol)
+
+ print("Connecting")
+ mc.connect()
+
+ if args.register:
+ print("Registering")
+ mc.register()
+ mc.save_token(args.token_file)
+ print("Saved token to:", args.token_file)
+
+ if not mc.token:
+ if not os.path.isfile(args.token_file):
+ sys.exit("""No authentication token found, register with '-r' or specify path to token file with '-t '.Caution: After registration this device will lose coupling to all other apps (remove/add device in Mi Home app if needed). """)
+
+ print("Loading token from:", args.token_file)
+ mc.load_token(args.token_file)
+
+ print("Logging in...")
+ mc.login()
+
+ print("Retrieving serial number")
+
+ mc.comm_simplex("55aa032001 10 0e")
+ #print("Serial number:", resp.decode())
+ time.sleep(3)
+
+ #print("Retrieving firmware version")
+ #resp = mc.comm("55aa032001 1a 10")
+ #print("Firmware version:", f"{resp[0]}.{resp[1]}")
+
+ cmd = str(battery_info._raw_bytes.hex())
+ print("Sending command:", cmd)
+ def scooterPowerManagement(reboot=False):
+ mc.comm_simplex(Message() \
+ .set_direction(0x20) \
+ .set_read_write(ReadWrite.WRITE) \
+ .set_attribute(0x78 if reboot else 0x79) \
+ .set_payload(b'\x01\x00') \
+ .build()._raw_bytes.hex())
+
+ def on_message(client, userdata, msg):
+ print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
+ if msg.topic == topic +'cmds/poweroff':
+ scooterPowerManagement(True)
+ if msg.topic == topic +'cmds/reboot':
+ scooterPowerManagement(True)
+
+ mqtt.subscribe(topic+'cmds/#')
+ mqtt.on_message = on_message
+ mqtt.loop_start()
+ i = 0
+ while True:
+ i+=1
+ # ESC
+ if i % 10 == 0:
+ mc.comm_simplex('55AA 03 20 01 29 04') # Total mileage, m
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 2F 02') # Current mileage
+ time.sleep(0.05)
+
+ mc.comm_simplex('55AA 03 20 01 32 04') # Total run time
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 34 04') # ? some run time
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 3A 04') # ? trip time
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 3B 04') # ? trip time
+ time.sleep(0.05)
+
+ mc.comm_simplex('55AA 03 20 01 22 02') # BMS Percent
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 26 02') # Speed
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 47 02') # ESC supply voltage (measured by ESC)
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 48 02') # Battery voltage (from BMS)
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 50 02') # Battery current (from BMS)
+ time.sleep(0.05)
+ if i % 10 == 0:
+ mc.comm_simplex('55AA 03 20 01 75 02')
+ time.sleep(0.05)
+ # ESC Temperatures
+ if i % 10 == 0:
+ mc.comm_simplex('55AA 03 20 01 BB 02') #Frame temperature
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 20 01 3E 02') # Frame temperature
+ time.sleep(0.05)
+
+ # BMS
+ if i % 10 == 0:
+ mc.comm_simplex('55AA 03 22 01 40 14') # Cell Voltage 1 - 10
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 35 02') # bTemperature1:bTemperature2, Deg C, 0 is -20
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 30 02') # Status
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 33 02') #Current, x10mA, positive - discharging, negative - charging
+ time.sleep(0.05)
+ if i % 180 == 0:
+ mc.comm_simplex('55AA 03 22 01 10 0E') #Serial number
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 17 02') #Firmware version
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 18 02') #Factory capacity
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 20 02') #Manufacture date
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 1B 02') #Charge full cycles
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 1C 02') #Charge count
+ time.sleep(0.05)
+ mc.comm_simplex('55AA 03 22 01 3B 02') #Health, %
+ time.sleep(0.05)
+
+ print("Disconnecting")
+ mc.disconnect()
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file