Low level design for various types of Alexa Devices and battery-power-status-of-different-alexa-device
Here’s how the Alexa Device class can be filled with relevant details based on the Alexa device specifications, along with the corresponding interfaces for extensibility and proper abstraction.
Question
/ There are a wide variety of Alexa devices
// 1. Alexa devices that only have a speaker (Echo Dot, Echo Flex, https://www.amazon.com/dp/B07FZ8S74R)
// 2. Alexa devices that only have a screen/display (Alexa enabled Microwave or AC, https://www.amazon.com/dp/B07894S727)
// 3. Alexa devices that have both, speaker and screen (Echo Show, Echo Spot, https://www.amazon.com/dp/B08KJN3333).
// 4. Alexa devices that have neither a speaker, nor a screen (Echo Input, Echo link, https://www.amazon.com/dp/B0798DVZCY).
// 5. Alexa devices that have a speaker, but can be connected to a display (FireTV cube, https://www.amazon.com/dp/B08XMDNVX6).
//
// Also,
// 1. Some Alexa devices that have batteries (Fire Tablets, Echo Tap, Echo Buds, https://www.amazon.com/dp/B085WTYQ4X)
// 2. Others that do not have batteries (Echo Dot, Echo Show).
//
// Design a set of classes that will report the current battery/power status to the user.
// Depending on the hardware, the response may need to be spoken, or displayed on a screen, or both.
// Also, depending on whether there is a battery or not, the status message will differ.
// For example, if the device is a Tablet which has a battery, a speaker, and a display, and currently
// it happens to be plugged in and recharging (let's say at 75%), then your code should return the following:
// {
// "say": "Current battery level is 75% and charging",
// "display": "Current battery level is 75% and charging"
// }
//
// Whereas if the device is an Echo Dot, which has a speaker but no battery and no screen,
// then your code should only return:
// {
// "say": "Currently plugged into wall power"
// }
//
// and should NOT attempt to display anything (since there is no screen).
//
// For simplicity, ignore the details of speech generation and image/visual card generation, we can safely assume those are provided.
// Focus more on modeling the Alexa devices and their properties, and returning the correct responses.
Interfaces to be used
// Interface for devices that can speak messages
public interface ISpeaker {
void speak(String message);
}
// Interface for devices that can display messages
public interface IDisplay {
void display(String message);
}
// Interface for devices with a battery
public interface IBattery {
int getBatteryPercentage();
boolean isCharging();
}
// Interface for devices powered by an outlet
public interface IPluggedDevice {
boolean isPluggedIn();
}
Abstract Class: ADevice
public abstract class ADevice {
private final String deviceName;
public ADevice(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceName() {
return deviceName;
}
public abstract String getStatusMessage(); // Abstract method to be implemented by specific devices
}
Concrete Device Implementations
1. Devices with Speaker Only (e.g., Echo Dot)
public class SpeakerDevice extends ADevice implements ISpeaker, IPluggedDevice {
private boolean pluggedIn;
public SpeakerDevice(String deviceName, boolean pluggedIn) {
super(deviceName);
this.pluggedIn = pluggedIn;
}
@Override
public void speak(String message) {
System.out.println("Say: " + message);
}
@Override
public boolean isPluggedIn() {
return pluggedIn;
}
@Override
public String getStatusMessage() {
if (isPluggedIn()) {
return "Currently plugged into wall power";
}
return "Not plugged in, cannot operate";
}
}
2. Devices with Display Only (e.g., Alexa-Enabled Microwave)
public class DisplayDevice extends ADevice implements IDisplay, IPluggedDevice {
private boolean pluggedIn;
public DisplayDevice(String deviceName, boolean pluggedIn) {
super(deviceName);
this.pluggedIn = pluggedIn;
}
@Override
public void display(String message) {
System.out.println("Display: " + message);
}
@Override
public boolean isPluggedIn() {
return pluggedIn;
}
@Override
public String getStatusMessage() {
if (isPluggedIn()) {
return "Currently plugged into wall power";
}
return "Not plugged in, cannot operate";
}
}
3. Devices with Speaker and Display (e.g., Echo Show)
public class SpeakerDisplayDevice extends ADevice implements ISpeaker, IDisplay, IPluggedDevice {
private boolean pluggedIn;
public SpeakerDisplayDevice(String deviceName, boolean pluggedIn) {
super(deviceName);
this.pluggedIn = pluggedIn;
}
@Override
public void speak(String message) {
System.out.println("Say: " + message);
}
@Override
public void display(String message) {
System.out.println("Display: " + message);
}
@Override
public boolean isPluggedIn() {
return pluggedIn;
}
@Override
public String getStatusMessage() {
if (isPluggedIn()) {
return "Currently plugged into wall power";
}
return "Not plugged in, cannot operate";
}
}
4. Devices with Battery, Speaker, and Display (e.g., Fire Tablet)
public class BatterySpeakerDisplayDevice extends ADevice implements ISpeaker, IDisplay, IBattery {
private int batteryPercentage;
private boolean charging;
public BatterySpeakerDisplayDevice(String deviceName, int batteryPercentage, boolean charging) {
super(deviceName);
this.batteryPercentage = batteryPercentage;
this.charging = charging;
}
@Override
public void speak(String message) {
System.out.println("Say: " + message);
}
@Override
public void display(String message) {
System.out.println("Display: " + message);
}
@Override
public int getBatteryPercentage() {
return batteryPercentage;
}
@Override
public boolean isCharging() {
return charging;
}
@Override
public String getStatusMessage() {
if (isCharging()) {
return "Current battery level is " + getBatteryPercentage() + "% and charging";
} else {
return "Current battery level is " + getBatteryPercentage() + "% and discharging";
}
}
}
Usage Example
public class DeviceDemo {
public static void main(String[] args) {
// Speaker-only device
ADevice echoDot = new SpeakerDevice("Echo Dot", true);
System.out.println(echoDot.getDeviceName() + ": " + echoDot.getStatusMessage());
((ISpeaker) echoDot).speak(echoDot.getStatusMessage());
// Display-only device
ADevice microwave = new DisplayDevice("Alexa-Enabled Microwave", true);
System.out.println(microwave.getDeviceName() + ": " + microwave.getStatusMessage());
((IDisplay) microwave).display(microwave.getStatusMessage());
// Device with speaker and display
ADevice echoShow = new SpeakerDisplayDevice("Echo Show", true);
System.out.println(echoShow.getDeviceName() + ": " + echoShow.getStatusMessage());
((ISpeaker) echoShow).speak(echoShow.getStatusMessage());
((IDisplay) echoShow).display(echoShow.getStatusMessage());
// Device with battery, speaker, and display
ADevice fireTablet = new BatterySpeakerDisplayDevice("Fire Tablet", 75, true);
System.out.println(fireTablet.getDeviceName() + ": " + fireTablet.getStatusMessage());
((ISpeaker) fireTablet).speak(fireTablet.getStatusMessage());
((IDisplay) fireTablet).display(fireTablet.getStatusMessage());
}
}
public class BatteryManager {
private int batteryPercentage;
private boolean isCharging;
public BatteryManager(int batteryPercentage, boolean isCharging) {
if (batteryPercentage < 0 || batteryPercentage > 100) {
throw new IllegalArgumentException("Battery percentage must be between 0 and 100.");
}
this.batteryPercentage = batteryPercentage;
this.isCharging = isCharging;
}
public int getBatteryPercentage() {
return batteryPercentage;
}
public boolean isCharging() {
return isCharging;
}
public boolean isBatteryDrained() {
return batteryPercentage == 0 && !isCharging;
}
public String getBatteryStatus() {
if (isBatteryDrained()) {
return "Battery is drained and not charging.";
} else if (isCharging) {
return "Battery level is " + batteryPercentage + "% and charging.";
} else {
return "Battery level is " + batteryPercentage + "% and discharging.";
}
}
}
Github Link :-Alexa Device design