Smart Cities - Python MQTT class library: Difference between revisions
No edit summary Tag: Reverted |
Tag: Reverted |
||
| Line 145: | Line 145: | ||
= | = Car Class= | ||
Here’s a simple Python program demonstrating object-oriented programming (OOP) concepts. This program defines a basic Car class with attributes and methods to simulate a car's functionality. The program allows for easy expansion and modification. | Here’s a simple Python program demonstrating object-oriented programming (OOP) concepts. This program defines a basic Car class with attributes and methods to simulate a car's functionality. The program allows for easy expansion and modification. | ||
Revision as of 21:11, 29 September 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
Car Class
Here’s a simple Python program demonstrating object-oriented programming (OOP) concepts. This program defines a basic Car class with attributes and methods to simulate a car's functionality. The program allows for easy expansion and modification.
Simple Python Program: Car Class
# Simple Car Class Example
class Car:
def __init__(self, make, model, year):
"""Initialize the attributes of the car."""
self.make = make # The manufacturer of the car
self.model = model # The model of the car
self.year = year # The manufacturing year of the car
self.odometer_reading = 0 # Initialize the odometer reading to 0
def describe_car(self):
"""Return a neatly formatted descriptive name."""
return f"{self.year} {self.make} {self.model}"
def read_odometer(self):
"""Print a statement showing the car's mileage."""
print(f"This car has {self.odometer_reading} miles on it.")
def update_odometer(self, mileage):
"""Set the odometer to the given value."""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self, miles):
"""Add the given amount to the odometer."""
if miles > 0:
self.odometer_reading += miles
else:
print("You can't increment by a negative value!")
if __name__ == '__main__':
# Create an instance of the Car class
my_car = Car('Toyota', 'Corolla', 2020)
# Print the description of the car
print(my_car.describe_car())
# Update the odometer and read the mileage
my_car.update_odometer(15000)
my_car.read_odometer()
# Increment the odometer
my_car.increment_odometer(500)
my_car.read_odometer()
# Attempt to roll back the odometer (this will show an error)
my_car.update_odometer(10000) # This should show a warning
Explanation of the Code
Class Definition: Car
The class is defined using the class keyword. The __init__ method initializes the car’s attributes, such as make, model, year, and odometer_reading.
Methods:
- describe_car(self): Returns a string describing the car in a formatted way.
- read_odometer(self): Prints the current mileage of the car.
- update_odometer(self, mileage): Updates the odometer reading if the new mileage is greater than or equal to the current reading.
- increment_odometer(self, miles): Increases the odometer reading by a specified number of miles, only if the value is positive.
Main Script:
- An instance of the Car class is created (named my_car).
- The program prints the description of the car, updates the odometer, and shows how to use the various methods defined in the class.
- The program also demonstrates error handling when attempting to roll back the odometer.
Expanding the Program
Here are some ideas on how to expand this program:
Add More Attributes:
- Include attributes like color, fuel_type, or mileage_per_gallon.
- Create Derived Classes: Create subclasses, such as ElectricCar, that inherit from the Car class and add new methods or attributes (e.g., battery capacity).
- Implement a Maintenance Log: Add methods to track maintenance activities or repairs.
- Add User Input: Allow users to input car details when creating a new car object.
This simple program provides a solid foundation for learning OOP in Python and can easily be expanded upon as you gain more experience!
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.