"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Heating = void 0;
const room_1 = require("./room");
const device_1 = require("./device");
const types_1 = require("./types");
const utils_1 = require("./utils");
const axios_1 = __importDefault(require("axios"));
class Heating {
    constructor(mqttWorker) {
        this.wattsUsage = 1800;
        this.priceKWh = 0.165345;
        this.todayOnTimer = 0;
        this.yesterdayOnTimer = 0;
        this.sumaOnTimer = 0;
        this.roomTemperature = 0;
        this.roomTempTolerance = 0.3;
        this.wantedTemperature = 21.5;
        this.mode = types_1.Mode.AUTO;
        this.heating = types_1.Switch.OFF;
        this.lastStatusOn = 0;
        let setupTemperature = parseFloat(process.argv.slice(2).toString());
        this.mqttWorker = mqttWorker;
        this.room = new room_1.Room();
        this.device = new device_1.Device(mqttWorker);
        this.currentDate = (0, utils_1.getCurrentDate)();
        if (process.env.PRICE_KWH) {
            this.priceKWh = parseFloat(process.env.PRICE_KWH);
        }
        if (process.env.WATTS_USAGE) {
            this.wattsUsage = parseInt(process.env.WATTS_USAGE);
        }
        if (setupTemperature > 0) {
            this.wantedTemperature = setupTemperature;
        }
        this.init();
    }
    async init() {
        this.heating = await this.getStatus();
        this.heating = this.mqttWorker.getCurrentState();
        this.power = await this.device.getPowerUsage();
        this.roomTemperature = await this.getTemperature();
        this.todayOnTimer = 0;
        this.yesterdayOnTimer = 0;
        this.sumaOnTimer = 0;
        this.update();
        this.storePowerUsage();
        setInterval(() => {
            if (this.heating == types_1.Switch.ON) {
                this.todayOnTimer++;
                this.sumaOnTimer++;
            }
            // Check if we have a new day
            const currentDate = (0, utils_1.getCurrentDate)();
            if ((0, utils_1.getCurrentDate)() !== this.currentDate) {
                this.yesterdayOnTimer = this.todayOnTimer;
                this.todayOnTimer = 0;
                this.currentDate = currentDate;
            }
        }, 1000);
        setInterval(() => {
            const state = this.mqttWorker.getCurrentState();
            if (state !== this.heating) {
                this.heating = state;
                this.device.setState(state);
                this.showInfo();
            }
        }, 10000);
        setInterval(async () => {
            this.power = await this.device.getPowerUsage();
            this.storePowerUsage();
        }, 1000 * 60 * 10); // 10 Minutes
    }
    async update() {
        let temp = this.mqttWorker.getRoomTemperature();
        if (temp === null) {
            temp = await this.getTemperature();
        }
        this.roomTemperature = temp;
        this.heating = await this.getStatus();
        this.checkRoomHeatingStatus();
        // Debug Info
        this.showInfo();
    }
    setTemperature(newTemp) {
        this.wantedTemperature = newTemp;
        this.update();
    }
    setMode(newMode) {
        this.mode = newMode;
        this.update();
    }
    raiseTemperature(change = 0.1) {
        this.wantedTemperature += change;
    }
    lowerTemperature(change = 0.1) {
        this.wantedTemperature -= change;
    }
    getStats() {
        return {
            status: this.heating,
            mode: this.mode,
            temp: {
                room: this.roomTemperature,
                set: this.wantedTemperature,
            },
            heating: {
                today: {
                    time: (this.todayOnTimer).toFixed(0),
                    price: this.getPrice(),
                },
                suma: {
                    time: (this.sumaOnTimer).toFixed(0),
                    price: this.getPriceSuma(),
                }
            },
            power: this.power,
        };
    }
    async storePowerUsage() {
        let today = 0;
        let yesterday = 0;
        if (this.power.daily !== undefined) {
            if (this.power.daily[0] !== undefined) {
                today = this.power.daily[0].usage;
            }
            if (this.power.daily[1] !== undefined) {
                yesterday = this.power.daily[1].usage;
            }
        }
        try {
            const res = await axios_1.default.post('https://homedata.top/api/power_usage', {
                today: today,
                yesterday: yesterday,
                todayOnTimer: this.todayOnTimer,
                yesterdayOnTimer: this.yesterdayOnTimer,
            });
        }
        catch (err) {
            console.log("POST POWER USAGE", err.message);
        }
    }
    checkRoomHeatingStatus() {
        if (this.roomTemperature === null) {
            return;
        }
        // Check if we are in AUTO mode, otherwise do nothing...
        if (this.mode === types_1.Mode.MANUAL) {
            return;
        }
        // Check if we need to turn ON heating
        if (this.roomTemperature < this.wantedTemperature) {
            if (this.heating === types_1.Switch.OFF) {
                let now = new Date().getTime();
                let razlika = now - this.lastStatusOn;
                if (razlika > 600) {
                    this.setState(types_1.Switch.ON);
                }
                else {
                    console.log("SECURITY: TO CLOSE TO TURN ON");
                }
            }
        }
        // Check if we need to turn OFF heating
        //const neededTemp:number = this.roomTemperature + this.roomTempTolerance;
        if (this.roomTemperature > this.wantedTemperature) {
            if (this.heating === types_1.Switch.ON) {
                this.setState(types_1.Switch.OFF);
                this.lastStatusOn = new Date().getTime();
            }
        }
    }
    async getStatus() {
        return this.device.getStatus();
    }
    async getTemperature() {
        return await this.room.getTemperature();
    }
    async setState(state) {
        if (state === this.heating) {
            return;
        }
        this.heating = await this.device.setState(state);
        this.update();
    }
    getPriceSuma(toPrecision = 4) {
        const watts = this.wattsUsage / 1000;
        const price = watts * this.priceKWh / 3600 * this.sumaOnTimer;
        return price.toFixed(toPrecision);
    }
    getPrice(toPrecision = 4) {
        const watts = this.wattsUsage / 1000;
        const price = watts * this.priceKWh / 3600 * this.todayOnTimer;
        return price.toFixed(toPrecision);
    }
    showInfo() {
        let output = '';
        if (this.mode == types_1.Mode.AUTO) {
            output = "\x1b[35mAUTO   \x1b[0m";
        }
        else {
            output = "\x1b[36mMANUAL \x1b[0m";
        }
        if (this.heating == types_1.Switch.ON) {
            output += "\x1b[32mON \x1b[0m";
        }
        else {
            output += "\x1b[31mOFF \x1b[0m";
        }
        let wTemp = this.wantedTemperature;
        if (!isNaN(this.wantedTemperature)) {
            wTemp = this.wantedTemperature.toPrecision(4);
        }
        output += " 🏠 \x1b[33m" + this.roomTemperature + " °C\x1b[0m";
        output += " 🌡️ \x1b[34m" + wTemp + " °C\x1b[0m";
        output += " ⌚️ " + (0, utils_1.secondsToTime)(this.todayOnTimer) + "";
        output += " 💶 " + this.getPrice() + " €";
        output += " ⌚️ " + (0, utils_1.secondsToTime)(this.sumaOnTimer) + "";
        output += " 💶 " + this.getPriceSuma() + " €";
        console.log(output);
    }
}
exports.Heating = Heating;
//# sourceMappingURL=heating.js.map