This article is part two of another article How To Make Smart Home Automation Using ESP32 Module? in which a method to make a Smart Home System was provided. In this article, we are going to demonstrate the step by step procedure of how to develop an android application and connect it t the firebase database. Then this mobile application will be used to switch the electrical appliances in the home.

Android App Development
Smart Home Systems that are already available in the market are very costly. If you have the necessary components and an android device, you can make a home automation system at home which will be equally efficient but will be very low in cost. Go through these two articles to make your own Home Automation System at home.
How To Develop An Android Application For Home Automation?
Step 1: Software Needed
As we are going to develop an android application, we will need just one software. But to run that software, we will need to install another software first. You can download them from the following links.
- Android Studio.
- JAVA JDK.
Step 2: Understanding The Main Working
We are going to make an application that will have both front-end and back-end coding. On the main screen, it will contain some buttons that will control the switching of the electrical appliances that are connected to the ESP32 microcontroller board. In the back-end coding, We will send a “1” if the switch is on and a “0” if the switch is off.
We are going to make a Firebase database. This database will contain 2 entities named as Light and AC. The light will contain the value for the switching of lights and AC will contain a value for the switching of the fan. This value will be then sent to the microcontroller and then the microcontroller will send a control signal to the relay module accordingly.
Step 3: Setting Up Android Studio
Before installing Android Studio, we will install JAVA JDK first. To install this, click on the exe file that you downloaded from the above link, and click next until it is successfully installed. Now Go through the following steps so that your command prompt recognizes java as an external or internal command.
- Open Control Panel and click on System and Security .
- Click on System . System
- Click on Advanced System Setting and then click on Environmental Variables . Advanced System Setting
- In the System Variable section, click on the path and then click on edit. A new Edit Environmental Variable box will appear. Edit Path
- Now go to C:\Program Files\Java in your PC. Open the JDK folder, click on the bin folder and then copy the path of that folder. Path of the bin folder
- Now go to the Edit Environmental Variable box and click on new to make a new variable. Paste the path that you copied in the above step in the new variable and save it.
- Now to confirm, if it is completely installed, open command prompt and type java –version . JAVA version
Now as you have successfully installed Java JDK on your computer. Let us now install Android Studio on your computer. Installing this software is very easy. You need to open the downloaded file and click next until your software is fully installed.
Step 4: Making The Layout
We will make a layout that will contain some buttons which will send the command of 0 or 1 to the firebase database. This will be a simple layout that will contain some buttons. In my app, I will just include two buttons that will control the lights and the fan. If you want to include more buttons for more home appliances, copy the same chunk of code in the main program and make a new variable in the database. Without wasting any time, let us move towards the steps of making a simple layout for our app.
First of all, go to File > New > New Project. A menu will appear. Select Empty Project.
Now name the project and set KOTLIN as your programming language.
Now on the left corner, click on app > res > layout > activity_main.xml.

activity_main
- Here, add the following code below the code that is already provided in your android studio. We are making a constraint layout. The following code is adding a heading of Room Automation on the top. It is then adding 3 switches. one switch allows you to select f you want to operate the home appliances manually or not. The other two switched will operate the fan and the lights respectively.
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:fontFamily="sans-serif-medium"
android:text="Room Automation"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.528"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.063" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Air Conditioner"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.086"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.416" />
<Switch
android:id="@+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Mannual"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.887"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.258" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Lights"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.073"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.498" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="Menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.749" />
<TextView
android:id="@+id/textView6"
android:layout_width="167dp"
android:layout_height="38dp"
android:layout_marginStart="8dp"
android:layout_marginTop="140dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Switch on to operate manually."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.114"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<Switch
android:id="@+id/toggleButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="AC"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.808"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.421" />
<Switch
android:id="@+id/toggleButton3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Lights"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.811"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
- The Layout of your app will look like the image below.

Layout
Step 5: Back-End Coding
The back end code is the most important part of any application. It is the main bridge between the front-end layout and the database of the project. In our application, we just want to send a “1” in the database when the switch is on and a “0” in the database when the switch is off. Go through the following steps to add the code in your application
On the left corner, click on app > java > com.example.my applicationmyapplication > main_activity.
Now on this screen, copy the following code in your class.
class automation : AppCompatActivity() {
var database = FirebaseDatabase.getInstance()
var myRef = database.reference
internal lateinit var btnSwitch:Switch
internal lateinit var btnSwitch1:Switch
internal lateinit var btnSwitch2:Switch
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_automation)
myRef.child("Toggle/switch").addValueEventListener(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
switch1.visibility = View.VISIBLE
if (p0.value.toString().equals("1")){
switch1.isChecked = true;
toggleButton2.visibility = View.VISIBLE
toggleButton3.visibility = View.VISIBLE
myRef.child("automation/AC").addValueEventListener(object :ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if(p0.value.toString().equals("1")){
toggleButton2.isChecked = true
}
else
toggleButton2.isChecked = false
}
})
myRef.child("automation/light").addValueEventListener(object :ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if(p0.value.toString().equals("1")){
toggleButton3.isChecked = true
}
else
toggleButton3.isChecked = false
}
})
}
else{
switch1.isChecked = false
toggleButton2.visibility = View.GONE
toggleButton3.visibility = View.GONE
}
// Log.d("ahsan", p0.value.toString())
}
})
button3.setOnClickListener{
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
btnSwitch = findViewById<View>(R.id.switch1) as Switch
btnSwitch1 = findViewById<View>(R.id.toggleButton2) as Switch
btnSwitch2 = findViewById<View>(R.id.toggleButton3) as Switch
btnSwitch.setOnClickListener{
if(btnSwitch.isChecked)
{
myRef.child("Toggle/switch").setValue("1")
btnSwitch1.setOnClickListener{
if(btnSwitch1.isChecked)
{
myRef.child("automation/AC").setValue("1")
}
else
{
myRef.child("automation/AC").setValue("0")
}
}
btnSwitch2.setOnClickListener{
if(btnSwitch2.isChecked)
{
myRef.child("automation/light").setValue("1")
}
else
{
myRef.child("automation/light").setValue("0")
}
}
}
else
{
myRef.child("Toggle/switch").setValue("0")
}
}
}
}
Right now, the code may give some errors at some points because it is not connected to the firebase database right now. We will make a firebase database and connect it to the application.
Step 6: Connecting The App To Firebase Database
Connecting the firebase database to the android app is almost the final step. We are going to make a database on Firebase. Firebase is a mobile and web application improvement stage that furnishes designers with plenty of devices and administrations to enable them to grow top-notch applications, develop their client base, and acquire more benefits. Firebase is providing us two services that are Real-Time Database and Firestore.

Connectivity Between App And Firebase
We will make a Real-Time Database on which all the values will be updated in real-time with a delay f some seconds. Go through the following steps to make a real-time database on firebase. Android studio provides a very simple method to make this connection. Go through the following steps to establish this connection.
- Click n Tools. A drop-down menu will appear from which, select Firebase.

Firebase
- A big menu will appear on the right side of the screen that will be providing the menu of almost every service that firebase is providing. But right now our main focus is on Real-Time Database. So click on Real-Time Database. A link to “ Save and Retrieve Data ” will appear. Click that link.

Real-Time Database
- Connect on Connect To Firebase button. It will take you to the default web browser. First, it will ask you to log-in to your Gmail account.

Connect to Firebase
Now click on Add the Realtime Database to your app button from the menu shown in the image above. A box will appear asking to make some changes. Click on Ac cept changes. You will see that the application will start syncing to connect to our Real-Time Database.
Now go to Firebase Console . There you will see a project already made. The android logo on that projet’s icon means that it already belongs to an android application.

Project
From the Develop menu that appears on the left side of the screen, select Database. A button of Create Database will appear on the right. Click on that button.
A menu will appear asking to set the mode of your database. Click on test mode and then click Enable .

Test Mode
- Now a really important step to remember is to change the Cloud Firestore to Real-Time Database. To do so click on the button shown in the below image and change the desired option.

Change to RT Database
- Now click on the Rules tab and change the configurations to True . Once everything is done, click Publish .

Changing Configurations
- One thing that you need to do other than connecting the firebase, is to update the database version. For that, click on go to docs . Now click on guides and select Android Guides from the list that appears on the screen. Scroll down until a table appears. Look for Real-Time Database in that table and find its version. in my case, it is 19.1.0

Version
- Click on Gradle Scripts, a menu on the left side of the screen. Then select built. gradle (Module: app). Now in the code, search for the version of the Real-Time database and replace it by the new one.

Update Version
Now our Firebase Connection with our Android app is fully established. We can now proceed towards the testing part of our project.
Step 7: Testing
The Testing part is very simple. You just need to go to your Android device and enable the Developers Options from the setting. Then you will need to enable the USB Debugging. After doing all this, connect your Android device to your computer and run the android project in android studio. This will build the app on your android device.
Now, click the buttons on your screen and it will automatically make the entities on your firebase database. You will see that some values will be updated in their corresponding entity as you press the buttons.
How to Fix “Printer is in an error state” Issue?
- Recognizing the importance of a printer’s duty cycle is crucial for choosing a device that matches your print volume needs. Staying within this limit ensures the printer operates efficiently and prolongs its lifespan, minimizing the risk of maintenance issues.
- Proper humidity, temperature, and cleanliness management can significantly enhance printer performance and maintain its duty cycle, preventing unnecessary wear.
- Enhancing a printer with upgrades like additional memory or better mechanical parts can improve its workload handling and extend its practical duty cycle, boosting overall durability and efficiency.
When choosing a new printer, you might come across the term “ duty cycle ” in the specifications. This guide will explain what a duty cycle is, why it matters, and how it can help you choose the right printer. We’ll keep things simple so you can easily understand how to use this information when shopping for a printer.
- Printer Duty Cycle: What It Means and Why It Matters?
- Why the Duty Cycle Is Key to Choosing the Right Printer?
- Duty Cycle vs. Recommended Monthly Print Volume: What’s the Difference?
- What Happens If You Ignore Printer Duty Cycle Recommendations? ↪ Real-World Scenarios: Why Exceeding the Duty Cycle Can Cost You
Printer Duty Cycle: What It Means and Why It Matters?

What is the meaning of Printer Duty Cycle?
The printer duty cycle represents the upper limit of a printer’s capacity—how many pages it can reliably process in a month before the risk of wear or malfunction increases. This figure is crucial for understanding printer performance limits and ensuring that your chosen printer can handle the expected work volume.
Manufacturers determine a printer’s duty cycle through stress testing, where the printer is pushed to its limit to identify how many pages it can produce each month before malfunctioning. These tests help set a reliable performance gateway for users.
A printer’s duty cycle is like a car’s speedometer—you wouldn’t drive a car at top speed all the time, and you shouldn’t push a printer to its maximum duty cycle. Doing so can lead to quicker wear and tear, more frequent maintenance, and a shorter lifespan.
If you’re unsure whether to choose an inkjet or laser printer, this detailed guide compares both options to help you make an informed decision.
Why the Duty Cycle Is Key to Choosing the Right Printer?

The Importance of Duty Cycle in printer selection
Knowing the duty cycle is essential when choosing a printer, as it determines how well the device can handle your monthly print volume without excessive wear or maintenance.
Here is why the duty cycle matters in printer selection:
- Fit for purpose: Selecting a printer with a suitable duty cycle ensures it can handle your monthly printing volume efficiently, reducing stress on its components.
- Longer lifespan and better performance: Staying within the duty cycle ensures optimal print quality and speed while prolonging the printer’s life, avoiding frequent breakdowns.
- Cost efficiency and reduced downtime: Operating within the duty cycle minimizes the need for repairs and reduces operational disruptions, managing long-term costs.
Duty Cycle vs. Recommended Monthly Print Volume: What’s the Difference?

Duty Cycle vs. recommended monthly print volume
The recommended monthly print volume is the optimal number of pages a printer should handle each month for the best performance and longevity. Unlike the maximum capacity indicated by the duty cycle, this number guides regular usage, ensuring the printer operates efficiently without excessive wear.
If your print volume regularly exceeds the recommended amount but stays within the duty cycle, the printer may operate safely in the short term, but it could still experience accelerated wear and reduced lifespan over time.
In such cases, consider upgrading to a higher-capacity printer or spreading print jobs across multiple devices to ensure long-term performance.
Here are the differences between the duty cycle and recommended monthly print volume:
- Duty cycle: Represents the maximum number of pages a printer can handle in a month without breaking down. It assesses the printer’s upper limit.
- Recommended monthly print volume: Suggests a practical, workable number of pages to print each month to keep the printer in good condition over its lifespan.
What Happens If You Ignore Printer Duty Cycle Recommendations?

Consequences of ignoring Duty Cycle recommendations |AndranikHakobyan via Canva
Ignoring the duty cycle limits poses more severe risks than exceeding the recommended monthly print volume, leading to serious long-term consequences.
While exceeding the recommended volume occasionally may result in additional wear and tear, consistently exceeding the duty cycle can lead to frequent breakdowns, reduced performance, and a shortened lifespan.
Ignoring duty cycle limits leads to frequent breakdowns, reduced performance, and increased maintenance, ultimately shortening the printer’s lifespan and causing more frequent operational downtime and higher repair costs. Long-term, pushing a printer beyond its limits leads to greater financial burdens due to premature replacements and inefficiencies.
↪ Real-World Scenarios: Why Exceeding the Duty Cycle Can Cost You
For example, in a busy law firm, overlooking duty cycle limits during a high-stakes period could cause a printer breakdown just before a critical deadline, delaying crucial legal filings and ultimately compromising client service.
For small businesses, consistently exceeding a printer’s duty cycle can lead to costly emergency repairs or premature equipment replacements, straining financial resources.