import { PolymerElement, html } from '../node_modules/@polymer/polymer/polymer-element.js';
import '../node_modules/@polymer/app-layout/app-header/app-header.js';
import '../node_modules/@polymer/app-layout/app-layout.js';
import '../node_modules/@polymer/app-layout/app-scroll-effects/effects/waterfall.js';
import '../node_modules/@polymer/iron-icon/iron-icon.js';
import '../node_modules/@polymer/iron-icons/iron-icons.js';
import '../node_modules/@polymer/iron-icons/av-icons.js';
import '../node_modules/@polymer/iron-icons/communication-icons.js';
import '../node_modules/@polymer/iron-icons/device-icons.js';
import '../node_modules/@polymer/iron-icons/image-icons.js';
import '../node_modules/@polymer/iron-icons/hardware-icons.js';
import '../node_modules/@polymer/iron-icons/maps-icons.js';
import '../node_modules/@polymer/iron-icons/notification-icons.js';
import '../node_modules/@polymer/iron-icons/places-icons.js';
import '../node_modules/@polymer/iron-icons/social-icons.js';
import '../node_modules/@polymer/iron-list/iron-list.js';
import '../node_modules/@polymer/paper-dialog/paper-dialog.js';
import '../node_modules/@polymer/paper-icon-button/paper-icon-button.js';
import '../node_modules/@polymer/paper-toast/paper-toast.js';
import '../node_modules/@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
import '../node_modules/@polymer/paper-item/paper-item-body.js';
import '../node_modules/@polymer/paper-item/paper-icon-item.js';
import '../node_modules/@polymer/paper-listbox/paper-listbox.js';
import '../node_modules/@polymer/paper-item/paper-item.js';
import './smart-device.js';
import { SmartLight } from './smart-light.js';
import { SmartBlinds } from './smart-blinds.js';
import { SmartScene } from './smart-scene.js';
import { SmartOutlet } from './smart-outlet.js';
import { SmartSwitch } from './smart-switch.js';
export const SMART_HOME_CLOUD_ENDPOINT = '/smart-home-api';
let nextDeviceId = 0;
let nipx = 0;
const getNextDeviceId = () => {
return nextDeviceId++;
}; //Get the information of the url parameters to show to the user
function info() {
let query = window.location.search.substr(1); //Get all the parameters contained in the URL after "?"
// Split each parameter into a key-value pair
let keyValues = query.split('&');
let parameter = new Map();
for (let i in keyValues) {
// Split into =
let param = keyValues[i];
let splitParam = param.split('=');
parameter.set(splitParam[0], splitParam[1]);
}
if (parameter.get('info') == 'dataok') {
alert('Vos données ont bien été mises à jour.');
}
if (parameter.get('info') == 'nopass') {
alert('La modification a échoué !\nLe mot de passe est incorrect.');
}
}
info();
/**
* Container class which manages smart devices.
*/
export class MyApp extends PolymerElement {
/**
* @return {string} HTML tag.
*/
static get template() {
return html`
Vous n'avez pas encore lié d'IPX800_V4 à votre compte, vous pouvez le
faire dès maintenant en cliquant le bouton en haut à gauche, onglet "Mes IPXs".
Souhaitez-vous vraiment vous déconnecter ?
OuiNon
Mes IPXs
1
-
2
-
3
-
4
-
5
-
EnregistrerAnnuler
Mon compte
Modifier mes identifiants
Modifier mon mot de passe
Supprimer mon compte
OK
Modifier mes identifiants
EnregistrerAnnuler
Modifier mon mot de passe
EnregistrerAnnuler
Confirmer la suppression du compte?
OuiNon
Ajouter un appareil
Vous n'avez pas d'appareils connectés pour le moment. Pour ajouter un appreil,
cliquez sur le bouton "+" en haut à doite.
`;
}
/**
* @return {object} Properties of this class
*/
static get properties() {
return {
hide: {
type: Boolean,
value: false
},
hideAlert: {
type: Boolean,
value: true
},
deviceCount: {
type: Number,
value: 0
},
lights: {
type: Array,
value: []
},
blinds: {
type: Array,
value: []
},
thermostats: {
type: Array,
value: []
},
scenes: {
type: Array,
value: []
},
fans: {
type: Array,
value: []
},
kettles: {
type: Array,
value: []
},
coffeemakers: {
type: Array,
value: []
},
outlets: {
type: Array,
value: []
},
switchs: {
type: Array,
value: []
},
sprinklers: {
type: Array,
value: []
}
};
}
/**
* Callback that runs when the HTML element is created.
*/
connectedCallback() {
if (!IPXS || Object.keys(IPXS).length == 0) {
this.hideAlert = false;
} else {
this.hideAlert = true;
}
super.connectedCallback();
this.ExistDevice(); //display the existed devices
this._initipxs(); //init the IPXs dialog box
// event to open the different dialog boxes
window.requestAnimationFrame(() => {
this.$.add.addEventListener('tap', e => this.$.modal.open());
this.$.disco.addEventListener('tap', e => this.$.discomodal.open()); //When we click on the button with the "account" id in the toolbar dropdown menu, the "accountsettings" dialog box opens
this.$.account.addEventListener('tap', e => this.$.accountsetting.open());
this.$.myipx.addEventListener('tap', e => this.$.myipxsetting.open());
this.$.changeids.addEventListener('tap', e => this.$.accountid.open());
this.$.changepassword.addEventListener('tap', e => this.$.accountpass.open());
this.$.deleteAccount.addEventListener('tap', e => this.$.DeleteConf.open());
});
} //function called when clicking the '+' on the IPXs dialog box
_showPassword() {
if (this.$.new_password.type == "password") {
this.$.new_password.type = "text";
this.$.show_password.icon = "visibility-off";
} else {
this.$.new_password.type = "password";
this.$.show_password.icon = "visibility";
}
}
_showConfirmPassword() {
if (this.$.confirm_password.type == "password") {
this.$.confirm_password.type = "text";
this.$.show_confirm_password.icon = "visibility-off";
} else {
this.$.confirm_password.type = "password";
this.$.show_confirm_password.icon = "visibility";
}
}
_addIPX() {
nipx++;
this.$['ipx' + nipx].style.display = 'flex';
if (nipx == 5) {
this.$['addIPX'].style.display = 'none';
}
} //function called when clicking on the bin icon of a device
_deleteIPX(event) {
let path = event.path || event.composedPath && event.composedPath();
this.$[path[3].id].style.display = 'none'; //even.path[3].id represent the id (form: ipx+'number')
this.$['name' + path[3].id].value = ''; // of the ipx we wish to delete
this.$['mac' + path[3].id].value = '';
nipx--;
this.$['addIPX'].style.display = 'flex';
} //initialize the IPXs list of the user in the dialog box
_initipxs() {
var that = this;
if (IPXS != null && Object.keys(IPXS).length != 0) {
//if at least 1 IPX is already stored
Object.keys(IPXS).forEach(function (name) {
nipx++;
that.$['nameipx' + nipx].value = name;
that.$['macipx' + nipx].value = IPXS[name];
that.$['ipx' + nipx].style.display = 'flex';
});
} else {
nipx++;
that.$['nameipx' + nipx].value = '';
that.$['macipx' + nipx].value = '';
that.$['ipx' + nipx].style.display = 'flex';
}
} //function called when cliccking on the 'Enregistrer' button of the dialog box
_storeipxs() {
IPXS = {};
for (var i = 1; i < 6; i++) {
if (this.$['ipx' + i].style.display == 'flex') {
IPXS[this.$['nameipx' + i].value] = this.$['macipx' + i].value;
}
}
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
ipxs: IPXS
})
};
fetch(SMART_HOME_CLOUD_ENDPOINT + '/ipxs', options).then(() => {
//it send the IPXs list to the database
window.location.reload();
});
}
_disconnect() {
// return fetch('/disconnect');
// Remove cache data
this.$['iddisco'].submit();
} //function which is called when clicking on 'enregister' on the 'Modifier mes identifiants' dialog box,
_setaccountid() {
if (this.$['username'].value != window.USERNAME || this.$['email'].value != window.EMAIL) {
//Check if one of the ids have changed
this.$['newname'].value = this.$['username'].value;
this.$['newemail'].value = this.$['email'].value;
this.$['confirmpass'].value = this.$['password'].value;
this.$['idform'].submit(); //If true, submit the account information form
}
} //function which is called when clicking on 'enregister' on the 'Modifier mon mot de passe' dialog box,
_setaccountpass() {
if (this.$['new_password'].value == this.$['confirm_password'].value) {
//Check if the passwords enterred are the same
this.$['oldpass'].value = this.$['old_password'].value;
this.$['newpass'].value = this.$['new_password'].value;
this.$['passform'].submit(); //If true, submit the password form
} else {
alert('Les mots de passes sont différents !');
}
} //function which is called when clicking on 'oui' on the delete account form dialog box,
_deleteAccount() {
this.$['confpass'].value = this.$['confirm_delete'].value;
this.$['deleteform'].submit(); //If true, submit the delete form
}
/**
* Shows message in a progress dialog box.
* @param {string} message Message to display.
*/
showProgress(message) {
this.$['progress-dialog-content'].innerHTML = message || 'no message';
this.$['progress-dialog'].show();
}
/**
* Closes progress dialog box.
*/
hideProgress() {
this.$['progress-dialog'].close();
}
/**
* Shows a message that there are no devices.
*/
showNoDeviceMessage() {
this.hide = false;
}
/**
* Hides a message that there are no devices.
*/
hideNoDeviceMessage() {
this.hide = true;
}
/**
* Removes a device.
* @param {string} type The type of device to remove.
* @param {number} index The index of the device of this type.
*/
removeDevice(type, index, deviceId) {
this.splice(type, index, 1); //delete the device in the devices tab
this.hide = --this.deviceCount > 0;
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
userId: UID,
deviceId: deviceId
})
};
return fetch(SMART_HOME_CLOUD_ENDPOINT + '/remove-device', options); //send request to delete in DB
}
/**
* Displays a toast message.
* @param {string} toastmsg The message to be displayed.
*/
showToast(toastmsg) {
this.$.toast.text = toastmsg;
this.$.toast.open();
}
/**
* get the user data to show it in the frontend application (menu display).
*/
_showData() {
this.$['nameUser'].innerHTML = window.USERNAME;
this.$['mailUser'].innerHTML = window.EMAIL;
this.$['username'].value = window.USERNAME;
this.$['email'].value = window.EMAIL;
}
_genUuid() {
return Math.floor(Math.random() * 100000).toString(36);
}
/**
* Creates a new device
* @param {object} device The device that is being created. It can be
* undefined.
* @return {Promise} A promise.
* If the device parameter exists and has
* an id, it resolves with the device object. If the promise is
* rejected, the device has not been defined and must be created.
* The rejection includes the device id to use.
*/
_createDevice(device) {
this.$['progress-dialog'].close(); // Close modal
this.hideNoDeviceMessage();
this.deviceCount++; // If the device variable exists, resolve to use it
if (device && device.hasOwnProperty('id')) {
return Promise.resolve(device);
} // Otherwise reject the variable and create a new one
return Promise.reject(getNextDeviceId());
}
/**
* Adds a new device to a particular device type array.
* @param {string} type The type of device.
* @param {object} device The device object.
*/
_addDevice(type, device) {
this.push(type, device);
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
userId: UID,
device: device
})
};
return fetch(SMART_HOME_CLOUD_ENDPOINT + `/register-device`, options).then(() => {}).catch(error => {
console.error('>>> failed to register device in DB');
});
}
/**
* Adds a new smart light that supports RGB colors.
* @param {object} light The device object
*/
_addLight(light) {
this._createDevice(light).then(device => {
this._addDevice('lights', device);
}).catch(lightId => {
this._addDevice('lights', SmartLight.generateRgb(lightId, this.lights.length));
});
}
/**
* Adds a new smart light that supports monochrome.
* @param {object} light The device object
*/
_addMonochromeLight(light) {
this._createDevice(light).then(device => {
this._addDevice('lights', device);
}).catch(lightId => {
this._addDevice('lights', SmartLight.generateMonochrome(lightId, this.lights.length));
});
}
/**
* Adds a new smart blinds.
* @param {object} blinds The device object
*/
_addBlinds(blinds) {
this._createDevice(blinds).then(device => {
this._addDevice('blinds', device);
}).catch(blindsId => {
this._addDevice('blinds', SmartBlinds.generate(blindsId, this.blinds.length));
});
}
/**
* Creates a new scene to control all lights at once.
* @param {object} scene The device object
*/
_addScene(scene) {
this._createDevice(scene).then(device => {
this._addDevice('scenes', device);
}).catch(sceneId => {
this._addDevice('scenes', SmartScene.generate(sceneId, this.scenes.length));
});
}
/**
* Adds a new smart outlet
* @param {object} outlet The device object
*/
_addOutlet(outlet) {
this._createDevice(outlet).then(device => {
this._addDevice('outlets', device);
}).catch(outletId => {
this._addDevice('outlets', SmartOutlet.generate(outletId, this.outlets.length));
});
}
/**
* Adds a new smart switch
* @param {object} smartswitch The device object
*/
_addSwitch(smartswitch) {
this._createDevice(smartswitch).then(device => {
this._addDevice('switchs', device);
}).catch(switchId => {
this._addDevice('switchs', SmartSwitch.generate(switchId, this.switchs.length));
});
} // /**
// * Adds a new smart thermostat.
// * @param {event} event
// * @param {object} thermostat The device object
// */
// _addThermostat(event, thermostat) {
// this._createDevice(thermostat)
// .then((device) => {
// this._addDevice('thermostats', device);
// })
// .catch((thermostatId) => {
// this._addDevice('thermostats',
// SmartThermostat.generate(thermostatId,
// this.thermostats.length));
// });
// }
//
// /**
// * Adds a new smart fan
// * @param {object} fan The device object
// */
// _addFan(fan) {
// this._createDevice(fan)
// .then((device) => {
// this._addDevice('fans', device);
// })
// .catch((fanId) => {
// this._addDevice('fans',
// SmartFan.generate(fanId,
// this.fans.length));
// });
// }
//
// /**
// * Adds a new smart kettle
// * @param {object} kettle The device object
// */
// _addKettle(kettle) {
// this._createDevice(kettle)
// .then((device) => {
// this._addDevice('kettles', device);
// })
// .catch((kettleId) => {
// this._addDevice('kettles',
// SmartKettle.generate(kettleId,
// this.kettles.length));
// });
// }
//
// /**
// * Adds a new smart coffee maker
// * @param {object} coffeeMaker The device object
// */
// _addCoffeeMaker(coffeeMaker) {
// this._createDevice(coffeeMaker)
// .then((device) => {
// this._addDevice('coffeemakers', device);
// })
// .catch((coffeemakerId) => {
// this._addDevice('coffeemakers',
// SmartCoffeeMaker.generate(coffeemakerId,
// this.coffeemakers.length));
// });
// }
//
// /**
// * Adds a new smart sprinkler
// * @param {object} sprinkler The device object
// */
// _addSprinkler(sprinkler) {
// this._createDevice(sprinkler)
// .then((device) => {
// this._addDevice('sprinklers', device);
// })
// .catch((sprinklerId) => {
// this._addDevice('sprinklers',
// SmartSprinkler.generate(sprinklerId,
// this.sprinklers.length));
// });
// }
/**
* Add the devices that have already been added by the user
* in previous connnections to the serveur
*/
//function called for each devices saved
_addExistDevice(data) {
var type = data.type;
if (type != 'blinds') {
type += 's';
}
var propDevice = data.device;
this._createDevice(propDevice).then(propDevice => {
this._addDevice(type, propDevice);
nextDeviceId++;
}).catch(() => {
this._addDevice(type, propDevice);
});
}
/**
* Function called when the page is loaded or refreshed
* Get all devices of the javascript app
*/
ExistDevice() {
var allDevices = window.DEVICES;
for (var i = 0; i < allDevices.length; i++) {
//for all the devices contained in 'allDevices'
var type = allDevices[i].properties.type.split(".")[3].toLowerCase(); //get the type of the device (necessary to create a device
var data = {
type: type,
device: allDevices[i]
};
this._addExistDevice(data);
}
}
}
window.customElements.define('my-app', MyApp);