diff --git a/.gitignore b/.gitignore index 723ef36..1f1025f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.idea \ No newline at end of file +.idea +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 0b84026..45363b8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Unfortunately not all cities work with the Trashcan Reminder, if you can find yo - [afvalwijzerArnhem](https://www.afvalwijzer-arnhem.nl) - [Gemeente Hellendoorn](http://hellendoornafvalkalender.2go-mobile.com) - [Twentemilieu](https://www.twentemilieu.nl) -- [recycleManager] (http://www.recyclemanager.nl) +- [recycleManager](http://www.recyclemanager.nl) If your city is not supported you can always add your schedule manually. If you wish to contribute to the project (for example by adding support for a city) I would advise you to take a look at [this explanation](https://github.com/apstemmer/com.athom.trashchecker/blob/master/developers) diff --git a/app.js b/app.js index 8386773..1481c3d 100644 --- a/app.js +++ b/app.js @@ -1,672 +1,682 @@ /*globals Homey, module, require, setInterval*/ "use strict"; +const Homey = require('homey'); +const DateTimeHelper = require('./lib/datetime.js'); + var http = require('http'); var apiArray = require('./trashapis.js'); -var gdates = ''; -var manualInput = false; var supportedTypes = ["GFT","PLASTIC","PAPIER","PMD","REST","TEXTIEL"]; -function init() { - // Update manual input dates when settings change. - Homey.manager('settings').on('set', onSettingsChanged); - Homey.manager('flow').on('condition.days_to_collect', flowDaysToCollect); - Homey.manager('speech-input').on('speech', parseSpeach); - - // Check if we have to handle manual input, or automatically. - if(Homey.manager('settings').get('manualInput')) +class TrashcanReminder extends Homey.App +{ + onInit() { - var manually = Homey.manager('settings').get('manualInput'); - manualInput = Boolean(manually); - } - - // Manually kick off data retrieval - onUpdateData(); - - // Every 24 hours update API or manual dates - setInterval(onUpdateData, 86400000); // Every 24-hours -} - -module.exports.init = init; -module.exports.updateAPI = updateAPI; - -/* ****************** - SPEECH FUNCTIONS -********************/ -function parseSpeach(speech, callback) { - //Homey.log('parseSpeach()', speech); - //console.log(speech); - speech.triggers.some(function (trigger) { - switch (trigger.id) { - case 'trash_collected' : - - // TYPE OF QUESTIONS - // WHAT type of trash is collected << TODAY | TOMORROW | DAY AFTER TOMORROW >> - // WHEN is <> collected? - // IS <> colllected << TODAY | TOMORROW | DAY AFTER TOMORROW >> - // WHICH type will be collected << TODAY | TOMORROW | DAY AFTER TOMORROW >> + this.manualInput = false; + this.gdates = ''; - var regexReplace = new RegExp("(" +__('speech.replacequestion')+ ")", 'gi'); - var newTranscript = speech.transcript.replace(regexReplace, ""); + // Update manual input dates when settings change. + Homey.on('settings.set', this.onSettingsChanged.bind(this)); - /* ****************** - FIND TRASH TYPE INDICATOR - ********************/ - var foundType = null; - var differenceInDaysForType = null; - for (var i = 0, len = supportedTypes.length; i < len; i++) { - if (newTranscript.indexOf(__('speech.type.' + supportedTypes[i])) > -1) - { - foundType = supportedTypes[i]; - break; // stop loop after first match. - } - - // Other words for types (search via regex) - var regex = new RegExp("(" +__('speech.type_multipleother.' + supportedTypes[i])+ ")", 'gi'); - if (newTranscript.match(regex) !== null) - { - foundType = supportedTypes[i]; - break; // stop loop after first match. - } - } - - // Find first collection date for this type of trash - if(foundType != null && typeof gdates[ foundType ] !== 'undefined') - { - var today = new Date(); - for (var i = 0, len = gdates[foundType].length; i < len; i++) - { - var date = new Date(gdates[foundType][i].substring(6,10), (parseInt(gdates[foundType][i].substring(3,5))-1), gdates[foundType][i].substring(0,2)); - - if(daysBetween(today, date) >= 0) - { - differenceInDaysForType = daysBetween(today, date); - break; - } - } - } + // Register flow card + let daysToCollect = new Homey.FlowCardCondition('days_to_collect'); + daysToCollect + .register() + .registerRunListener(this.flowDaysToCollect.bind(this)); - //console.log("type and difference in days"); - //console.log(foundType); - //console.log(differenceInDaysForType); + // Register speech events + Homey.ManagerSpeechInput.on('speechEval', this.speechEvalExecute.bind(this)); + Homey.ManagerSpeechInput.on('speechMatch', this.parseSpeechExecute.bind(this)); - /* ****************** - FIND TIME INDICATOR - ********************/ - var checkDate = null; - var typeCollectedOnThisDay = []; - var matchesWithGivenType = false; - // If bigger then one, someone probably asked something like 'is the container picked up tomorrow or the day after tomorrow' - if(speech.time != null && speech.time !== false && speech.time.length == 1) + // Check if we have to handle manual input, or automatically. + if(Homey.ManagerSettings.get('manualInput')) { - var dateInput = null; - try { - dateInput = new Date(speech.time[0].time.year, speech.time[0].time.month, speech.time[0].time.day); - } catch(e) { console.log(e); } - - //console.log("given date via speech"); - //console.log(dateInput); - checkDate = dateInput; + var manually = Homey.ManagerSettings.get('manualInput'); + this.manualInput = Boolean(manually); } + + // Manually kick off data retrieval + this.onUpdateData(); + + // Every 24 hours update API or manual dates + setInterval(this.onUpdateData.bind(this), 86400000); // Every 24-hours + + this.log("App initialized"); + } + + /* ****************** + SPEECH FUNCTIONS + ********************/ + speechEvalExecute(speech, callback) + { + callback ( null, true) + return; - if(checkDate != null) + var result = this.parseSpeech(speech, this.gdates); + if(result != null && result != "") { - // Go through types - for (var i = 0, len = supportedTypes.length; i < len; i++) { - if( typeof gdates[ supportedTypes[i] ] !== 'undefined' ) - { - if(gdates[ supportedTypes[i] ].indexOf(dateToString(checkDate)) > -1 && typeCollectedOnThisDay.indexOf(__('speech.type.' + supportedTypes[i])) <= -1) - { - typeCollectedOnThisDay.push(__('speech.output.type.' + supportedTypes[i])); - if(!matchesWithGivenType) - { - matchesWithGivenType = supportedTypes[i] == foundType; - } - } - } - } + //speech.say( result ); - //console.log("types collected on this day"); - //console.log(typeCollectedOnThisDay); + callback(null, true); + return true; } + + // Only execute 1 trigger + callback(null, false); + return false; + } + + parseSpeechExecute(speech, onSpeechEvalData) + { + console.log("parsing speech"); - /* ****************** - FIND TYPE OF QUESTION (sentence starting with WHAT, IS, WHEN) - ********************/ - var questionType = 0; - if(newTranscript.toLowerCase().startsWith(__('speech.questiontype.what')) || - newTranscript.toLowerCase().startsWith(__('speech.questiontype.which'))) - { - questionType = 1; - } - else if(newTranscript.toLowerCase().startsWith(__('speech.questiontype.when'))) + var result = this.parseSpeech(speech, this.gdates); + if(result != null && result != "") { - questionType = 2; - } - else if(newTranscript.toLowerCase().startsWith(__('speech.questiontype.is'))) - { - questionType = 3; + speech.say( result ); + + callback(null, true); + return true; } - - //console.log("defined question type"); - //console.log(questionType); - var responseText = ""; - try { - // which, what type of trash is collected <