Smart Cities - Python MQTT class library: Difference between revisions
Tag: Reverted |
Tag: Reverted |
||
| Line 144: | Line 144: | ||
= Bank Account Class = | = Bank Account Class = | ||
Revision as of 10:24, 27 October 2024
MQTT Class library
This Python program implements an MQTT client using the Paho MQTT library. It creates a simple class called Mqtt that can subscribe to and publish messages on MQTT topics, typically used in home automation systems. Let’s break down the program step by step.
#Home automation system MQTT class library
#Copyright (c) 2024, Julie VK3FOWL and Joe VK3YSP.
#For The School Amater Radio Club Network (r) VK3SRC.
#This program:
# Implements a Message Queuing Telemetry Transport (MQTT) client
# Subscribes to MQTT topics
# Publishes MQTT messages
import paho.mqtt.client as mqtt
class Mqtt(object):
def __init__(self, host, port, callback):
#Constructor
self.client = mqtt.Client() #Create an mqtt client
self.client.on_message = callback #Assign a message handler
if (self.client.connect(host, port, 60) == 0): #Connect to the mqtt broker
print('Connected to MQTT broker')
self.client.loop_start() #Start handling mqtt messages
print('MQTT client started')
def subscribe(self, topic):
#Subscribe to an mqtt topic
self.client.subscribe(topic)
def publish(self, topic, message):
#Subscribe to an mqtt topic
self.client.publish(topic, message)
if __name__ == '__main__': #Run this code stand-alone
#Test script - This script creates a MQTT object and demonstrates subscribing and publishing messages
def mqttCallback(client, userdata, message):
#This function handles received MQTT messages
print(f'MQTT: {message.topic}: {message.payload.decode()}') #Print the topic and message
mqttIP = 'localhost' #Assume the MQTT broker is running on this machine
mqttPort = 1883 #The standard MQTT port
mqtt = Mqtt(mqttIP, mqttPort, mqttCallback) #Create an MQTT object
mqtt.subscribe('Test1') #Subscribe to the Test1 topic
mqtt.subscribe('Test2') #Subscribe to the Test2 topic
mqtt.publish('Test1','Message1') #Publish a message to the Test1 topic
mqtt.publish('Test2','message2') #Publish a message to the Test2 topic
Imports
import paho.mqtt.client as mqtt
This imports the Paho MQTT library, which provides tools for creating and managing MQTT clients. MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol often used for IoT and home automation systems.
The Mqtt Class
This class encapsulates the MQTT functionality, allowing you to create an MQTT client, subscribe to topics, and publish messages.
Constructor: __init__(self, host, port, callback)
def __init__(self, host, port, callback):
self.client = mqtt.Client() # Create an mqtt client
self.client.on_message = callback # Assign a message handler
if (self.client.connect(host, port, 60) == 0): # Connect to the mqtt broker
print('Connected to MQTT broker')
self.client.loop_start() # Start handling mqtt messages
print('MQTT client started')
- self.client = mqtt.Client(): Creates an instance of the MQTT client.
- self.client.on_message = callback: Assigns a callback function to handle incoming messages. The callback function is passed as a parameter when creating an instance of the Mqtt class.
- self.client.connect(host, port, 60): Connects the MQTT client to the MQTT broker, using the specified host (IP address or domain name) and port (commonly 1883 for unencrypted MQTT). 60 refers to the keep-alive interval in seconds, which helps maintain the connection to the broker. If the connection is successful (returns 0'), it prints a success message.
- self.client.loop_start(): Starts a background thread that handles the sending and receiving of MQTT messages, so you don't have to block the main thread.
subscribe(self, topic)
def subscribe(self, topic):
self.client.subscribe(topic)
This method allows the client to subscribe to a specific MQTT topic. When subscribed, the client will receive all messages published to this topic.
publish(self, topic, message)
def publish(self, topic, message):
self.client.publish(topic, message)
This method allows the client to publish a message to a specific MQTT topic. Any subscribers to that topic will receive the message.
Main Script (Testing the Class)
if __name__ == '__main__':
def mqttCallback(client, userdata, message):
print(f'MQTT: {message.topic}: {message.payload.decode()}')
This callback function mqttCallback handles incoming messages. Whenever the client receives a message, it will print the topic and the message content.
- message.topic: The topic on which the message was published.
- message.payload.decode(): The actual message content, decoded from bytes to a string.
mqttIP = 'localhost' # IP address of the MQTT broker (running on the same machine)
mqttPort = 1883 # Standard port for unencrypted MQTT traffic
mqtt = Mqtt(mqttIP, mqttPort, mqttCallback) # Create an instance of the Mqtt class
- Here, we define the MQTT broker's IP address (localhost in this case, meaning the broker is running on the same machine) and the port (1883, the default for MQTT).
- A new Mqtt object is created using the broker's IP, port, and the mqttCallback function for handling messages.
mqtt.subscribe('Test1') # Subscribe to the 'Test1' topic
mqtt.subscribe('Test2') # Subscribe to the 'Test2' topic
mqtt.publish('Test1','Message1') # Publish 'Message1' to the 'Test1' topic
mqtt.publish('Test2','message2') # Publish 'message2' to the 'Test2' topic
- The client subscribes to two topics: Test1 and Test2.
- It then publishes messages to both topics:
- Test1 receives the message "Message1".
- Test2 receives the message "message2".
How the Program Works
- The MQTT client connects to the broker at localhost:1883.
- It subscribes to two topics (Test1 and Test2).
- It publishes messages to both of these topics.
- Whenever a message is published to one of these topics, the subscribed client receives the message, and the callback function (mqttCallback) is triggered to print out the message details.
Example Workflow
- The client connects to the MQTT broker at localhost on port 1883.
- It subscribes to two topics: Test1 and Test2.
- The client then publishes two messages: "Message1" to Test1 and "message2" to Test2.
- The subscribed client receives these messages, and the mqttCallback prints out:
MQTT: Test1: Message1
MQTT: Test2: message2
Bank Account Class
Here’s another simple object-oriented programming (OOP) example to help students practice. This one involves creating a Bank Account class, which simulates the basic functionality of a bank account. Like the previous example, it's designed for easy expansion.
# Simple Bank Account Class Example
class BankAccount:
def __init__(self, account_holder, balance=0):
"""Initialize the account holder's name and balance."""
self.account_holder = account_holder # Account holder's name
self.balance = balance # Initialize with an optional balance (default is 0)
def deposit(self, amount):
"""Deposit money into the account."""
if amount > 0:
self.balance += amount
print(f"Deposited ${amount}. New balance: ${self.balance}.")
else:
print("Deposit amount must be positive!")
def withdraw(self, amount):
"""Withdraw money from the account."""
if amount > 0 and amount <= self.balance:
self.balance -= amount
print(f"Withdrew ${amount}. Remaining balance: ${self.balance}.")
elif amount > self.balance:
print("Insufficient funds!")
else:
print("Withdrawal amount must be positive!")
def display_balance(self):
"""Display the current balance."""
print(f"Account balance: ${self.balance}")
if __name__ == '__main__':
# Create an instance of the BankAccount class
my_account = BankAccount('John Doe', 100) # Initial deposit of $100
# Display the current balance
my_account.display_balance()
# Perform a deposit
my_account.deposit(50) # Deposit $50
# Perform a withdrawal
my_account.withdraw(30) # Withdraw $30
# Attempt to withdraw more than the balance
my_account.withdraw(150) # Insufficient funds example
# Display the final balance
my_account.display_balance()
Explanation of the Code
Class Definition: BankAccount
- The class is defined to simulate a simple bank account.
- The __init__ method initializes the account holder’s name and an optional balance (default is 0).
Methods:
- deposit(self, amount): Adds money to the account, ensuring the amount is positive.
- withdraw(self, amount): Withdraws money from the account, ensuring the amount does not exceed the balance.
- display_balance(self): Prints the current account balance.
Main Script:
- An instance of the BankAccount class is created with an initial deposit.
- The program demonstrates depositing and withdrawing money and checks for insufficient funds.
- It prints the balance after each transaction.
Expanding the Program
Students can expand this example in several ways:
- Add Interest: Implement a method to apply interest to the account balance.
- Overdraft Protection: Add an overdraft limit and handle what happens when a withdrawal exceeds the overdraft limit.
- Multiple Accounts: Create a system to manage multiple bank accounts (e.g., savings and checking).
- Transaction History: Add a feature that tracks and prints all deposits and withdrawals.
This example builds upon the basics of OOP and encourages students to experiment with new features and functionalities.