lab6: add javadoc comments and polish the code
This commit is contained in:
		
							parent
							
								
									bd6a285f8f
								
							
						
					
					
						commit
						d2535d233f
					
				@ -1,33 +1,145 @@
 | 
			
		||||
public class Appliance {
 | 
			
		||||
/*
 | 
			
		||||
 * %W% %E% Dymik739
 | 
			
		||||
 * Email: dymik739@109.86.70.81
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2023 FIOT Dev Team
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU 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 General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class representing a general appliance and containing basic methods
 | 
			
		||||
 * that are used in multiple child classes. Supposed to be extended by
 | 
			
		||||
 * other classes and not to be used as a standalone class.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dymik739
 | 
			
		||||
 * @since 0.3
 | 
			
		||||
 */
 | 
			
		||||
public class Appliance implements Comparable<Appliance> {
 | 
			
		||||
    /** Indicates if this device is drawing power from the power network. */
 | 
			
		||||
    private boolean powerConnected;
 | 
			
		||||
 | 
			
		||||
    /** Defines the type of this device */
 | 
			
		||||
    private String type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for this class. Should be called only from within
 | 
			
		||||
     * constructors of other classes which inherit this one.
 | 
			
		||||
     *
 | 
			
		||||
     * @param connected defines if the device is connected to the network
 | 
			
		||||
     *                  at the start
 | 
			
		||||
     */
 | 
			
		||||
    public Appliance(boolean connected) {
 | 
			
		||||
        this.powerConnected = connected;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Getter for checking the power connection.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if connected and false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    public boolean getPowerState() {
 | 
			
		||||
        return powerConnected;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Getter for the device type variable.
 | 
			
		||||
     *
 | 
			
		||||
     * @return device type string
 | 
			
		||||
     */
 | 
			
		||||
    public String getType() {
 | 
			
		||||
        return type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Setter for setting the device type string.
 | 
			
		||||
     * Should be used only from the constructors of the classes
 | 
			
		||||
     * which inherit this one!
 | 
			
		||||
     *
 | 
			
		||||
     * @param type type of the device
 | 
			
		||||
     */
 | 
			
		||||
    public void setType(String type) {
 | 
			
		||||
        this.type = type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for connecting power to the device.
 | 
			
		||||
     */
 | 
			
		||||
    public void plug() {
 | 
			
		||||
        powerConnected = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for disconnecting power from the device.
 | 
			
		||||
     */
 | 
			
		||||
    public void unplug() {
 | 
			
		||||
        powerConnected = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for getting the smaller value out of two.
 | 
			
		||||
     *
 | 
			
		||||
     * @param v1 first value
 | 
			
		||||
     * @param v2 second value
 | 
			
		||||
     *
 | 
			
		||||
     * @return smaller value of the two given
 | 
			
		||||
     */
 | 
			
		||||
    public float min(float v1, float v2) {
 | 
			
		||||
        return v1 <= v2 ? v1 : v2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for getting the bigger value out of two.
 | 
			
		||||
     *
 | 
			
		||||
     * @param v1 first value
 | 
			
		||||
     * @param v2 second value
 | 
			
		||||
     *
 | 
			
		||||
     * @return bigger value of the two given
 | 
			
		||||
     */
 | 
			
		||||
    public float max(float v1, float v2) {
 | 
			
		||||
        return v1 >= v2 ? v1 : v2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Dummy method for getting the power consumption of the device.
 | 
			
		||||
     * Should be overridden by the child class!
 | 
			
		||||
     *
 | 
			
		||||
     * @return current power consumption.
 | 
			
		||||
     */
 | 
			
		||||
    public float getPowerConsumption() {
 | 
			
		||||
        return 0f;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Dummy method for performing the simulation.
 | 
			
		||||
     * Should be overridden by the child class!
 | 
			
		||||
     *
 | 
			
		||||
     * @param seconds delta time for the correct simulation step
 | 
			
		||||
     * @param ventRPM air flow created by the vent
 | 
			
		||||
     */
 | 
			
		||||
    public void step(float seconds, float ventRPM) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for comparing this appliance's power consumption to another
 | 
			
		||||
     * one. Part os the Comparable implementation.
 | 
			
		||||
     *
 | 
			
		||||
     * @param o another appliance to compare to
 | 
			
		||||
     *
 | 
			
		||||
     * @return difference between power consumption values
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public int compareTo(Appliance o) {
 | 
			
		||||
        return (int) (getPowerConsumption() - o.getPowerConsumption());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,58 @@
 | 
			
		||||
/*
 | 
			
		||||
 * %W% %E% Dymik739
 | 
			
		||||
 * Email: dymik739@109.86.70.81
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2023 FIOT Dev Team
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU 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 General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class which represents the behaviour of a dishwasher.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dymik739
 | 
			
		||||
 * @since 0.3
 | 
			
		||||
 */
 | 
			
		||||
public class Dishwasher extends Appliance {
 | 
			
		||||
    private float basePower = 160.0f;
 | 
			
		||||
    /** Defines power usage at different stages of washing dishes. */
 | 
			
		||||
    private float[] powerStates = {400f, 60f, 130f, 350f};
 | 
			
		||||
 | 
			
		||||
    /** Shows how much time should pass before switching to the next stage */
 | 
			
		||||
    private float nextPowerStateIn = 20f;
 | 
			
		||||
 | 
			
		||||
    /** Shows current stage the dishwasher is performing, -1 for none */
 | 
			
		||||
    private int currentState = -1;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for this class.
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugged sets the starting power state of this device
 | 
			
		||||
     */
 | 
			
		||||
    public Dishwasher(boolean plugged) {
 | 
			
		||||
        super(plugged);
 | 
			
		||||
        super.setType("Dishwasher");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for simulating the devices' behaviour.
 | 
			
		||||
     * Once started, it goes through every stage until it finishes washing
 | 
			
		||||
     * the dishes (every stage has it's own power usage level. After that,
 | 
			
		||||
     * it resets the device and turns it off automatically.
 | 
			
		||||
     *
 | 
			
		||||
     * @param seconds delta time to simulate for
 | 
			
		||||
     * @param ventRPM air flow created by the vent
 | 
			
		||||
     */
 | 
			
		||||
    public void step(float seconds, float ventRPM) {
 | 
			
		||||
        if (!super.getPowerState()) {
 | 
			
		||||
            return;
 | 
			
		||||
@ -24,7 +69,11 @@ public class Dishwasher extends Appliance {
 | 
			
		||||
            unplug();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Overridden method for turning on this device.
 | 
			
		||||
     * It automatically sets it to the correct stage and delay.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void plug() {
 | 
			
		||||
        super.plug();
 | 
			
		||||
@ -33,6 +82,10 @@ public class Dishwasher extends Appliance {
 | 
			
		||||
        nextPowerStateIn = 20f;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Overridden method for turning this device off.
 | 
			
		||||
     * It automatically resets the current washing stage to -1.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void unplug() {
 | 
			
		||||
        super.unplug();
 | 
			
		||||
@ -40,6 +93,12 @@ public class Dishwasher extends Appliance {
 | 
			
		||||
        currentState = -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for calculating the power consumption of this device.
 | 
			
		||||
     * Power usage depends on the current washing stage.
 | 
			
		||||
     *
 | 
			
		||||
     * @return float showing current power consumption
 | 
			
		||||
     */
 | 
			
		||||
    public float getPowerConsumption() {
 | 
			
		||||
        if (super.getPowerState()) {
 | 
			
		||||
            return powerStates[currentState];
 | 
			
		||||
@ -47,4 +106,18 @@ public class Dishwasher extends Appliance {
 | 
			
		||||
            return 0f;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for printing this devices' object in a nice way.
 | 
			
		||||
     *
 | 
			
		||||
     * @return String containing text description of this devices' state
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return String.format("Dishwasher(%s, %4.1fW, %2.1fs)",
 | 
			
		||||
                super.getPowerState() ? "on" : "off", getPowerConsumption(),
 | 
			
		||||
                super.getPowerState()
 | 
			
		||||
                        ? (3 - currentState) * 20 + nextPowerStateIn
 | 
			
		||||
                        : 0f);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										322
									
								
								labs/6/Main.java
									
									
									
									
									
								
							
							
						
						
									
										322
									
								
								labs/6/Main.java
									
									
									
									
									
								
							@ -1,8 +1,82 @@
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
/*
 | 
			
		||||
 * %W% %E% Dymik739
 | 
			
		||||
 * Email: dymik739@109.86.70.81
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2023 FIOT Dev Team
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU 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 General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main class that controls all the devices and regulates vent power.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dymik739
 | 
			
		||||
 * @since 0.3
 | 
			
		||||
 */
 | 
			
		||||
public class Main {
 | 
			
		||||
    /**
 | 
			
		||||
     * Defines the ServerRack power consumption at which the vent
 | 
			
		||||
     * power is enabled.
 | 
			
		||||
     */
 | 
			
		||||
    private static final float VENT_START_POWER = 240f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Defines the ServerRack power consumption at which the vent
 | 
			
		||||
     * power is disabled.
 | 
			
		||||
     */
 | 
			
		||||
    private static final float VENT_STOP_POWER = 185f;
 | 
			
		||||
 | 
			
		||||
    /** Defines magic number for real-time TTY output mode */
 | 
			
		||||
    private static final int TTY_LIVE_MONITORING_MODE = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Defines magic number for raw graph output mode for current
 | 
			
		||||
     * power consumption and vent RPM
 | 
			
		||||
     */
 | 
			
		||||
    private static final int POWER_RPM_GRAPH_MODE = 1;
 | 
			
		||||
 | 
			
		||||
    /** Defines magic number for raw graph output mode for total consumption */
 | 
			
		||||
    private static final int TOTAL_CONSUMPTION_GRAPH_MODE = 2;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Defines magic number for raw graph output mode for vent rpm and
 | 
			
		||||
     * power consumption relation
 | 
			
		||||
     */
 | 
			
		||||
    private static final int VENT_POWER_RPM_GRAPH_MODE = 3;
 | 
			
		||||
 | 
			
		||||
    /** Defines the amount of simulation samples to get per every second */
 | 
			
		||||
    private static final int TICKS_PER_SECOND = 720;
 | 
			
		||||
 | 
			
		||||
    /** Defines the time simulation will run for (in seconds) */
 | 
			
		||||
    private static final int SIMULATION_TIME = 240;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Main method for containing the devices, performing all
 | 
			
		||||
     * checks and plugging the devices in and out.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args accepts CLI arguments.
 | 
			
		||||
     */
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        Vent vent = new Vent(true);
 | 
			
		||||
        float ventConsumed = 0f;
 | 
			
		||||
        float totalPowerConsumed = 0f;
 | 
			
		||||
 | 
			
		||||
        int outputMode = parseMode(args);
 | 
			
		||||
        int liveStatsOutputDelay = parseOutputDelay(args);
 | 
			
		||||
 | 
			
		||||
        Vent vent = new Vent(false); // defining vent as a special appliance
 | 
			
		||||
 | 
			
		||||
        Appliance[] devices = {
 | 
			
		||||
            new ServerRack(false),
 | 
			
		||||
@ -11,53 +85,174 @@ public class Main {
 | 
			
		||||
            new Dishwasher(false)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        devices[0].plug();
 | 
			
		||||
        devices[2].plug();
 | 
			
		||||
        devices[2].plug(); // turning on RPI right away
 | 
			
		||||
                           // (RPI stands for Raspberry Pi)
 | 
			
		||||
        
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        float ventConsumed = 0f;
 | 
			
		||||
        float totalPowerConsumed = 0f;
 | 
			
		||||
        //for (int i = 0; i < 180*10; i++) {
 | 
			
		||||
        while (true) {
 | 
			
		||||
            step(vent, devices, 0.1f);
 | 
			
		||||
            ventConsumed += vent.getPowerConsumption() * 0.1;
 | 
			
		||||
            totalPowerConsumed += getTotalPowerConsumption(vent, devices) * 0.1 / 3600;
 | 
			
		||||
            //System.out.print(String.format("Time: %02.1f; ", (float) i/10)
 | 
			
		||||
            System.out.print("Time: " + floatFormat((float)i/10, 2, 1) + "; "
 | 
			
		||||
                             + getStats(vent, devices) + "; vent avg = "
 | 
			
		||||
                             + floatFormat(ventConsumed*10/i, 3, 1)
 | 
			
		||||
                             + "W; total = "
 | 
			
		||||
                             + floatFormat(totalPowerConsumed, 3, 3) + "W\r");
 | 
			
		||||
            if (devices[0].getPowerConsumption() > 205) {
 | 
			
		||||
                vent.plug();
 | 
			
		||||
        // letting the simulation run
 | 
			
		||||
        for (int i = 1; i <= SIMULATION_TIME*TICKS_PER_SECOND; i++) {
 | 
			
		||||
            step(vent, devices, (float) 1/TICKS_PER_SECOND); // stepping time
 | 
			
		||||
 | 
			
		||||
            // performing accounting
 | 
			
		||||
            ventConsumed += vent.getPowerConsumption() / TICKS_PER_SECOND;
 | 
			
		||||
            totalPowerConsumed += getTotalPowerConsumption(vent, devices)
 | 
			
		||||
                    / TICKS_PER_SECOND / 3600;
 | 
			
		||||
            
 | 
			
		||||
            // outputting the data in the desired format
 | 
			
		||||
            if (outputMode == TTY_LIVE_MONITORING_MODE) {
 | 
			
		||||
                System.out.print("Time: " + floatFormat((float)i/TICKS_PER_SECOND, 2, 2)
 | 
			
		||||
                        + "; " + getStats(vent, devices) + "; vent avg = "
 | 
			
		||||
                        + floatFormat(ventConsumed/TICKS_PER_SECOND/i, 4, 1)
 | 
			
		||||
                        + "W; total = "
 | 
			
		||||
                        + floatFormat(totalPowerConsumed, 4, 3) + "W\r");
 | 
			
		||||
            } else if (outputMode == POWER_RPM_GRAPH_MODE) {
 | 
			
		||||
                System.out.println(getTotalPowerConsumption(vent, devices)
 | 
			
		||||
                        + " " + vent.getRPM()/10);
 | 
			
		||||
            } else if (outputMode == TOTAL_CONSUMPTION_GRAPH_MODE) {
 | 
			
		||||
                System.out.println(totalPowerConsumed);
 | 
			
		||||
            } else if (outputMode == VENT_POWER_RPM_GRAPH_MODE) {
 | 
			
		||||
                System.out.println(vent.getRPM()/10 + " "
 | 
			
		||||
                        + vent.getPowerConsumption());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (devices[0].getPowerConsumption() < 190) {
 | 
			
		||||
                vent.unplug();
 | 
			
		||||
            adjustVentPower(devices, vent);
 | 
			
		||||
            
 | 
			
		||||
            managePower(i, devices);
 | 
			
		||||
            
 | 
			
		||||
            if ((outputMode == TTY_LIVE_MONITORING_MODE)
 | 
			
		||||
                    && (liveStatsOutputDelay != 0)) {
 | 
			
		||||
                try {
 | 
			
		||||
                    Thread.sleep(liveStatsOutputDelay);
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    System.exit(0);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (outputMode == TTY_LIVE_MONITORING_MODE) {
 | 
			
		||||
            Appliance[] totalDevices = new Appliance[devices.length + 1];
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < devices.length; i++) {
 | 
			
		||||
                totalDevices[i] = devices[i];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (i == 150) {
 | 
			
		||||
                devices[1].plug();
 | 
			
		||||
            } else if (i == 300) {
 | 
			
		||||
                devices[0].unplug();
 | 
			
		||||
            } else if (i == 400) {
 | 
			
		||||
                devices[3].plug();
 | 
			
		||||
            } else if (i == 700) {
 | 
			
		||||
                devices[0].plug();
 | 
			
		||||
            }
 | 
			
		||||
            totalDevices[devices.length] = vent;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                //TimeUnit.SECONDS.sleep(1);
 | 
			
		||||
                Thread.sleep(2);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                System.exit(0);
 | 
			
		||||
            }
 | 
			
		||||
            System.out.println("\nCurrently devices draw "
 | 
			
		||||
                    + floatFormat(getTotalPowerConsumption(totalDevices), 4, 2)
 | 
			
		||||
                    + "W from the power lines.");
 | 
			
		||||
 | 
			
		||||
            i++;
 | 
			
		||||
            Arrays.sort(totalDevices);
 | 
			
		||||
            printAppliances(totalDevices);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method which decides on how to manage the vent power supply.
 | 
			
		||||
     * It looks at power consumption of every ServerRack device
 | 
			
		||||
     * and:
 | 
			
		||||
     * - turns the vent on if ANY of them meet the VENT_START_POWER threshold
 | 
			
		||||
     * - turns the vent off if ALL of them meet the VENT_STOP_POWER threshold
 | 
			
		||||
     *
 | 
			
		||||
     * @param devices list of devices to look at.
 | 
			
		||||
     * @param vent vent to manage power for.
 | 
			
		||||
     */
 | 
			
		||||
    public static void adjustVentPower(Appliance[] devices, Vent vent) {
 | 
			
		||||
        for (Appliance i : devices) {
 | 
			
		||||
            if ("ServerRack".equals(i.getType())
 | 
			
		||||
                        && (i.getPowerConsumption() > VENT_START_POWER)) {
 | 
			
		||||
                vent.plug();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (Appliance i : devices) {
 | 
			
		||||
            if ("ServerRack".equals(i.getType())
 | 
			
		||||
                        && !(i.getPowerConsumption() < VENT_STOP_POWER)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        vent.unplug();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method that plugs in and out the devices in a predefined manner.
 | 
			
		||||
     *
 | 
			
		||||
     * @param i current simulation time.
 | 
			
		||||
     * @param devices device list to control.
 | 
			
		||||
     */
 | 
			
		||||
    public static void managePower(int i, Appliance[] devices) {
 | 
			
		||||
        if (i == 25 * TICKS_PER_SECOND) {
 | 
			
		||||
            devices[1].plug();
 | 
			
		||||
        } else if (i == 35 * TICKS_PER_SECOND) {
 | 
			
		||||
            devices[0].plug();
 | 
			
		||||
        } else if (i == 50 * TICKS_PER_SECOND) {
 | 
			
		||||
            devices[0].unplug();
 | 
			
		||||
        } else if (i == 60 * TICKS_PER_SECOND) {
 | 
			
		||||
            devices[3].plug();
 | 
			
		||||
        } else if (i == 130 * TICKS_PER_SECOND) {
 | 
			
		||||
            devices[0].plug();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for printing out a gives array of appliances.
 | 
			
		||||
     *
 | 
			
		||||
     * @param devices appliance array to print out.
 | 
			
		||||
     */
 | 
			
		||||
    public static void printAppliances(Appliance[] devices) {
 | 
			
		||||
        for (Appliance i : devices) {
 | 
			
		||||
            System.out.println(i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for extracting output mode setting set from CLI.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args CLI args array to use.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int representing requested mode.
 | 
			
		||||
     */
 | 
			
		||||
    public static int parseMode(String[] args) {
 | 
			
		||||
        for (String i : args) {
 | 
			
		||||
            if ("--power-rpm-graph".equals(i)) {
 | 
			
		||||
                return POWER_RPM_GRAPH_MODE;
 | 
			
		||||
            } else if ("--total-consumption-graph".equals(i)) {
 | 
			
		||||
                return TOTAL_CONSUMPTION_GRAPH_MODE;
 | 
			
		||||
            } else if ("--vent-monitoring-graph".equals(i)) {
 | 
			
		||||
                return VENT_POWER_RPM_GRAPH_MODE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return TTY_LIVE_MONITORING_MODE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for extracting output delay setting set from CLI.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args CLI args array to use.
 | 
			
		||||
     *
 | 
			
		||||
     * @return delay in miliseconds.
 | 
			
		||||
     */
 | 
			
		||||
    public static int parseOutputDelay(String[] args) {
 | 
			
		||||
        for (int i = 0; i < args.length; i++) {
 | 
			
		||||
            if ("--output-delay".equals(args[i])) {
 | 
			
		||||
                return Integer.parseInt(args[i+1]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 90;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for performing the simulation. Runs the respective .step()
 | 
			
		||||
     * methods on all of the given appliances.
 | 
			
		||||
     *
 | 
			
		||||
     * @param vent vent object to process
 | 
			
		||||
     * @param devices devices array to process
 | 
			
		||||
     * @param seconds delta time to move forward.
 | 
			
		||||
     */
 | 
			
		||||
    public static void step(Vent vent, Appliance[] devices, float seconds) {
 | 
			
		||||
        vent.step(seconds);
 | 
			
		||||
        for (Appliance i : devices) {
 | 
			
		||||
@ -65,6 +260,15 @@ public class Main {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for collecting the overall usage statistics to make it
 | 
			
		||||
     * easy to output status line during TTY mode execution.
 | 
			
		||||
     *
 | 
			
		||||
     * @param vent vent object to track
 | 
			
		||||
     * @param devices devices array to track
 | 
			
		||||
     *
 | 
			
		||||
     * @return String containing current stats for all the devices
 | 
			
		||||
     */
 | 
			
		||||
    public static String getStats(Vent vent, Appliance[] devices) {
 | 
			
		||||
        float[] powerConsumption = new float[devices.length];
 | 
			
		||||
        float totalPowerConsumption = 0;
 | 
			
		||||
@ -77,25 +281,29 @@ public class Main {
 | 
			
		||||
        String result = "PPD: ";
 | 
			
		||||
 | 
			
		||||
        for (float i : powerConsumption) {
 | 
			
		||||
            //result += String.format("%03.1fW ", i);
 | 
			
		||||
            result += String.format(floatFormat(i, 3, 1) + "W ");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        float powerLinesDraw = totalPowerConsumption
 | 
			
		||||
                + vent.getPowerConsumption();
 | 
			
		||||
 | 
			
		||||
        //result += String.format("; Vent: %03.1fW, %05.0f RPM; Total power: %04.1fW",
 | 
			
		||||
        result += "; Vent: " + floatFormat(vent.getPowerConsumption(), 3, 1)
 | 
			
		||||
                + "W, " + floatFormat(vent.getRPM(), 5, 0)
 | 
			
		||||
                + " RPM; Total power: " + floatFormat(powerLinesDraw, 4, 1)
 | 
			
		||||
                + "W";
 | 
			
		||||
                                //vent.getPowerConsumption(), vent.getRPM(),
 | 
			
		||||
                                //totalPowerConsumption + vent.getPowerConsumption());
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Overloaded method for calculating the total power consumption
 | 
			
		||||
     * (devices + the vent).
 | 
			
		||||
     *
 | 
			
		||||
     * @param vent vent to account
 | 
			
		||||
     * @param devices array of devices to account
 | 
			
		||||
     *
 | 
			
		||||
     * @return sum of all the .getPowerConsumption() returned from devices
 | 
			
		||||
     */
 | 
			
		||||
    public static float getTotalPowerConsumption(Vent vent,
 | 
			
		||||
            Appliance[] devices) {
 | 
			
		||||
        float result = vent.getPowerConsumption();
 | 
			
		||||
@ -107,6 +315,34 @@ public class Main {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Overloaded method for calculating the total power consumption
 | 
			
		||||
     * (devices only).
 | 
			
		||||
     *
 | 
			
		||||
     * @param devices array of devices to account
 | 
			
		||||
     *
 | 
			
		||||
     * @return sum of all the .getPowerConsumption() returned from devices
 | 
			
		||||
     */
 | 
			
		||||
    public static float getTotalPowerConsumption(Appliance[] devices) {
 | 
			
		||||
        float result = 0;
 | 
			
		||||
 | 
			
		||||
        for (Appliance a : devices) {
 | 
			
		||||
            result += a.getPowerConsumption();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Custom method which adds the support for arbitrary formatting of float
 | 
			
		||||
     * numbers.
 | 
			
		||||
     *
 | 
			
		||||
     * @param num value to format
 | 
			
		||||
     * @param leading amount of digits before period to print
 | 
			
		||||
     * @param trailing amount of digits after perio to print
 | 
			
		||||
     *
 | 
			
		||||
     * @return String with formatted result
 | 
			
		||||
     */
 | 
			
		||||
    public static String floatFormat(float num, int leading, int trailing) {
 | 
			
		||||
        String newNum = String.format("%0" + leading + "." + trailing + "f", num);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,59 @@
 | 
			
		||||
/*
 | 
			
		||||
 * %W% %E% Dymik739
 | 
			
		||||
 * Email: dymik739@109.86.70.81
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2023 FIOT Dev Team
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU 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 General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class which represents the RPI (Raspberry Pi) microcomputer.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dymik739
 | 
			
		||||
 * @since 0.3
 | 
			
		||||
 */
 | 
			
		||||
public class RPI extends Appliance {
 | 
			
		||||
    /** Contains current power draw from the power supply. */
 | 
			
		||||
    private float power = 15.0f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Defines the delay after the startup when the power usage starts to drop
 | 
			
		||||
     * to it's lowest value.
 | 
			
		||||
     */
 | 
			
		||||
    private float postBootDecreaseIn = 10.0f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for this class.
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugged sets the power state on the beginning
 | 
			
		||||
     */
 | 
			
		||||
    public RPI(boolean plugged) {
 | 
			
		||||
        super(plugged);
 | 
			
		||||
        super.setType("RPI");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method which is used to simulate the device's behaviour.
 | 
			
		||||
     * The device draws it's maximum power for postBootDecreaseIn
 | 
			
		||||
     * seconds and gradually drops to it's lowest level, after that
 | 
			
		||||
     * it always stays on the lowest power usage level until a
 | 
			
		||||
     * reboot happens.
 | 
			
		||||
     *
 | 
			
		||||
     * @param seconds delta time to simulate for
 | 
			
		||||
     * @param ventRPM air flow generated by the vent
 | 
			
		||||
     */
 | 
			
		||||
    public void step(float seconds, float ventRPM) {
 | 
			
		||||
        postBootDecreaseIn -= seconds;
 | 
			
		||||
 | 
			
		||||
@ -18,6 +66,24 @@ public class RPI extends Appliance {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Custom method for unplugging the device.
 | 
			
		||||
     * Adds the automatic resetting to the default values right after
 | 
			
		||||
     * turning the device off.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void unplug() {
 | 
			
		||||
        super.unplug();
 | 
			
		||||
 | 
			
		||||
        power = 15f;
 | 
			
		||||
        postBootDecreaseIn = 10f;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for getting the power draw of this device.
 | 
			
		||||
     *
 | 
			
		||||
     * @return current power consumption
 | 
			
		||||
     */
 | 
			
		||||
    public float getPowerConsumption() {
 | 
			
		||||
        if (super.getPowerState()) {
 | 
			
		||||
            return power;
 | 
			
		||||
@ -25,4 +91,15 @@ public class RPI extends Appliance {
 | 
			
		||||
            return 0f;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for printing this devices' object in a nice way.
 | 
			
		||||
     *
 | 
			
		||||
     * @return String containing text description of this devices' state
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return String.format("RPI(%s, %4.1fW)",
 | 
			
		||||
                super.getPowerState() ? "on" : "off", getPowerConsumption());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,28 +1,124 @@
 | 
			
		||||
/*
 | 
			
		||||
 * %W% %E% Dymik739
 | 
			
		||||
 * Email: dymik739@109.86.70.81
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2023 FIOT Dev Team
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU 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 General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class which represents a server rack.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dymik739
 | 
			
		||||
 * @since 0.3
 | 
			
		||||
 */
 | 
			
		||||
public class ServerRack extends Appliance {
 | 
			
		||||
    private String type = "ServerRack";
 | 
			
		||||
    /** Defines power used by the rack at lowest temperature. */
 | 
			
		||||
    private float basePower = 160.0f;
 | 
			
		||||
 | 
			
		||||
    /** Defines power limit for this rack */
 | 
			
		||||
    private float maxPower = 350.0f;
 | 
			
		||||
 | 
			
		||||
    /** Contains the inner temperature of this rack */
 | 
			
		||||
    private float temperature = 20f;
 | 
			
		||||
 | 
			
		||||
    /** Defines current usage of this device */
 | 
			
		||||
    private float currentLoad = 0.2f;
 | 
			
		||||
 | 
			
		||||
    /** Predicts the future change of the load */
 | 
			
		||||
    private float loadVector = +1f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for this class.
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugged defines if the device is plugged in at the start
 | 
			
		||||
     */
 | 
			
		||||
    public ServerRack(boolean plugged) {
 | 
			
		||||
        super(plugged);
 | 
			
		||||
        super.setType("ServerRack");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for simulating this device behaviour.
 | 
			
		||||
     * This rack processes video segments for the streaming platform and
 | 
			
		||||
     * serves them to the public in different qualities. Every device requires
 | 
			
		||||
     * the fragments to be encoded in it's respective format in order to play
 | 
			
		||||
     * the stream. As such, the load rises when new fragment arrives and falls
 | 
			
		||||
     * as it converts it into all the formats required.
 | 
			
		||||
     *
 | 
			
		||||
     * Temperature depends on many factors. Firstly, the device heats up while
 | 
			
		||||
     * performing tasks and the rate is affected by:
 | 
			
		||||
     * - current temperature (hotter = more power drawn);
 | 
			
		||||
     * - load on the CPU (more load = more heat);
 | 
			
		||||
     *
 | 
			
		||||
     * Of course, the temperature can be reduced using the vent installed in
 | 
			
		||||
     * the house. The rate of reduction is calculated using:
 | 
			
		||||
     * - current temperature (the bigger the difference compared to the outside
 | 
			
		||||
     *   temperature, the larger impact the vent has on it);
 | 
			
		||||
     * - air flow, created by the vent (the faster the air moves, the more
 | 
			
		||||
     *   heat it takes away from the system);
 | 
			
		||||
     *
 | 
			
		||||
     * This device can also cool itself down while standing still as the heat
 | 
			
		||||
     * slowly transfers to the air even when the vent doesn't force it.
 | 
			
		||||
     * The rate is calculated by only the temperature difference between inner
 | 
			
		||||
     * and outer temperatures.
 | 
			
		||||
     *
 | 
			
		||||
     * @param seconds delta time to simulate for
 | 
			
		||||
     * @param ventRPM air flow created by the vent
 | 
			
		||||
     */
 | 
			
		||||
    public void step(float seconds, float ventRPM) {
 | 
			
		||||
        if (super.getPowerState()) {
 | 
			
		||||
            temperature += min(basePower + (temperature - 20f) * 1.8f, maxPower)
 | 
			
		||||
                * seconds * 0.024f;
 | 
			
		||||
        currentLoad += loadVector/10 * seconds;
 | 
			
		||||
 | 
			
		||||
        if (currentLoad >= 1) {
 | 
			
		||||
            loadVector = -1f;
 | 
			
		||||
        } else if (currentLoad <= 0.2) {
 | 
			
		||||
            loadVector = +1f;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        temperature -= (temperature - 20f) * ventRPM*0.0003f * seconds;
 | 
			
		||||
        temperature -= 0.006f * (temperature - 20f) * seconds;
 | 
			
		||||
        if (super.getPowerState()) {
 | 
			
		||||
            temperature += min(basePower + (temperature - 20f) * 1.8f
 | 
			
		||||
                    * max(min(currentLoad, 1), 0), maxPower) * seconds
 | 
			
		||||
                    * 0.024f;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        temperature -= (temperature - 20f) * ventRPM * 0.00013f * seconds;
 | 
			
		||||
        temperature -= 0.002f * (temperature - 20f) * seconds;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method which calculates power consumption if this device.
 | 
			
		||||
     *
 | 
			
		||||
     * @return power consumption of this device
 | 
			
		||||
     */
 | 
			
		||||
    public float getPowerConsumption() {
 | 
			
		||||
        if (super.getPowerState()) {
 | 
			
		||||
            return min(basePower + (temperature - 20f) * 1.8f, maxPower);
 | 
			
		||||
            return min(basePower + (temperature - 20f) * 1.8f * max(min(currentLoad, 1), 0), maxPower);
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0f;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Overridden toString() method for printing the state of this device.
 | 
			
		||||
     *
 | 
			
		||||
     * @return String representing current state of this device
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return String.format("ServerRack(%s, %4.1fW, %3.1f℃C, %3.1f%%)",
 | 
			
		||||
                super.getPowerState() ? "on" : "off", getPowerConsumption(),
 | 
			
		||||
                temperature, currentLoad * 100);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										133
									
								
								labs/6/Vent.java
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								labs/6/Vent.java
									
									
									
									
									
								
							@ -1,13 +1,111 @@
 | 
			
		||||
public class Vent extends Appliance {
 | 
			
		||||
    private float maxPower = 90.0f;
 | 
			
		||||
    private float rpm = 0.0f;
 | 
			
		||||
    private final float rotorInertia = 7.0f;
 | 
			
		||||
    private final float maxRPM = 6500.0f;
 | 
			
		||||
/*
 | 
			
		||||
 * %W% %E% Dymik739
 | 
			
		||||
 * Email: dymik739@109.86.70.81
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2023 FIOT Dev Team
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU 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 General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class that represents a vent installed in the house.
 | 
			
		||||
 * This device acts as a reactive load.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dymik739
 | 
			
		||||
 * @since 0.3
 | 
			
		||||
 */
 | 
			
		||||
public class Vent extends Appliance {
 | 
			
		||||
    /**
 | 
			
		||||
     * Power draw limit set by the digital controller, designed by a KPI 
 | 
			
		||||
     * student. Built with the JK-triggers, may malfunction sometimes.
 | 
			
		||||
     * Exceeding this limit may damage the engine, so it's hard limited.
 | 
			
		||||
     */
 | 
			
		||||
    private float maxPower = 80.0f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Current rotor revolutions per minute.
 | 
			
		||||
     * Can also be defined as angular velocity or kinetic energy
 | 
			
		||||
     * accumulated in the device.
 | 
			
		||||
     */
 | 
			
		||||
    private float rpm = 0.0f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Defines inertia of the rotor.
 | 
			
		||||
     * Allows the rotor to withstand forces changing it's angular speed.
 | 
			
		||||
     */
 | 
			
		||||
    private final float rotorInertia = 2.0f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Target RPM the vent is tuned to maintain.
 | 
			
		||||
     * Rotor draws full power until it reaches this speed, after that it
 | 
			
		||||
     * draws only as much power as needed to maintain this speed.
 | 
			
		||||
     *
 | 
			
		||||
     * Might be tweaked up to match the exact RPM required, as the target
 | 
			
		||||
     * RPM is more than actual RPM while running due to additional forces
 | 
			
		||||
     * and failures in design of the microcontroller (it was also designed
 | 
			
		||||
     * using JK-triggers as they were the ones that student used in their
 | 
			
		||||
     * coursework last year).
 | 
			
		||||
     */
 | 
			
		||||
    private final float maxRPM = 2013.0f;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for this class.
 | 
			
		||||
     *
 | 
			
		||||
     * @param plugged defines if the device is plugged into the power
 | 
			
		||||
     *                network right away
 | 
			
		||||
     */
 | 
			
		||||
    public Vent(boolean plugged) {
 | 
			
		||||
        super(plugged);
 | 
			
		||||
        super.setType("Vent");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for simulating the device behaviour.
 | 
			
		||||
     * As was stated before in the class docs, this device has reactive
 | 
			
		||||
     * properties when it comes to loading the network. This means, it
 | 
			
		||||
     * doesn't only change it's power usage during operation, but also
 | 
			
		||||
     * follows some real-world physics laws while running.
 | 
			
		||||
     *
 | 
			
		||||
     * First, it uses the power, limited by a device microcontroller,
 | 
			
		||||
     * to gain angular velocity, measured in RPM. Right before it reaches
 | 
			
		||||
     * it's target RPM, the power draw falls with the exponential decrement
 | 
			
		||||
     * law (can be seen from the graph in --vent-monitoring-graph mode).
 | 
			
		||||
     *
 | 
			
		||||
     * Once it meets the target RPM, it draws power to only maintain it's
 | 
			
		||||
     * speed (the power goes to withstand air forces trying to slow the
 | 
			
		||||
     * fan - and the attached rotor - down).
 | 
			
		||||
     *
 | 
			
		||||
     * After the power cuts off, the fan keeps rotating due to it's inertia
 | 
			
		||||
     * and, when plugged back in, starts getting back up to it's target speed
 | 
			
		||||
     * according to it's current RPM. The power draw from the network always
 | 
			
		||||
     * meets the power used to gain angular velocity of the rotor.
 | 
			
		||||
     *
 | 
			
		||||
     * Also, as this vent is forcing the air through, the blades experience
 | 
			
		||||
     * the air drag - it always tries to slow the fan down. As such, the
 | 
			
		||||
     * air rag force is always calculated and depends of the RPM, which
 | 
			
		||||
     * is proportional to the force being put on the blades.
 | 
			
		||||
     *
 | 
			
		||||
     * And the engineering level is kind of weird: on one hand, they
 | 
			
		||||
     * engineer a smark device that can manage the RPM and limit the power
 | 
			
		||||
     * to the rotor, but on the other hand they're unable to deal with
 | 
			
		||||
     * reverse polarity the rotor generates while running, so they've
 | 
			
		||||
     * just soldered a single diode on the wire and thus limited possible
 | 
			
		||||
     * power down to just 80W! At least, the vent is still functional, so
 | 
			
		||||
     * I guess it's good enough...
 | 
			
		||||
     *
 | 
			
		||||
     * @param seconds delta time to simulate for
 | 
			
		||||
     */
 | 
			
		||||
    public void step(float seconds) {
 | 
			
		||||
        // electric current usage
 | 
			
		||||
        if (super.getPowerState()) {
 | 
			
		||||
@ -16,9 +114,15 @@ public class Vent extends Appliance {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // air drag (always present)
 | 
			
		||||
        rpm -= (rpm / 200) / rotorInertia;
 | 
			
		||||
        rpm -= (rpm / 20) / rotorInertia * seconds;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for calculating current power consumption of this device.
 | 
			
		||||
     * Calculations are similar to the step() method above.
 | 
			
		||||
     *
 | 
			
		||||
     * @return current power consumption of this device
 | 
			
		||||
     */
 | 
			
		||||
    public float getPowerConsumption() {
 | 
			
		||||
        if (super.getPowerState()) {
 | 
			
		||||
            return max(min(rotorInertia*(maxRPM - rpm), maxPower), 0);
 | 
			
		||||
@ -27,7 +131,24 @@ public class Vent extends Appliance {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Getter for RPM.
 | 
			
		||||
     *
 | 
			
		||||
     * @return current RPM
 | 
			
		||||
     */
 | 
			
		||||
    public float getRPM() {
 | 
			
		||||
        return rpm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Method for ptinting out this device state in a nice way.
 | 
			
		||||
     *
 | 
			
		||||
     * @return string representation of this device state
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return String.format("Vent(%s, %4.1fW, %4.0f RPM)",
 | 
			
		||||
                super.getPowerState() ? "on" : "off", getPowerConsumption(),
 | 
			
		||||
                rpm);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user