Skip to content

Commit

Permalink
chore: add ESlint (#32)
Browse files Browse the repository at this point in the history
* ignore node_modules

* add eslint

* add workflow

* fix findings
  • Loading branch information
CFenner authored Jan 4, 2024
1 parent d324a63 commit 260cb29
Show file tree
Hide file tree
Showing 8 changed files with 2,768 additions and 109 deletions.
15 changes: 15 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
env:
browser: true
es2022: true
node: true
jest: true
extends:
- standard
parserOptions:
sourceType: module
ecmaVersion: 2022
globals:
Module: true
Log: true
rules:
"comma-dangle": ["error", "always-multiline"]
28 changes: 28 additions & 0 deletions .github/workflows/validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: "Validation"

on:
push:
branches:
- main
pull_request:
branches:
- main
env:
node-version: 18.x

jobs:
eslint:
runs-on: ubuntu-latest
name: 'ESLint'
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Use Node.js ${{ env.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.node-version }}
cache: "npm"
- name: Install Dependencies
run: npm clean-install
- name: Validate JS Sources
run: npm run validate:js
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore all node modules.
node_modules
167 changes: 83 additions & 84 deletions MMM-AirQuality.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
* MIT Licensed.
*/
Module.register('MMM-AirQuality', {
// Default module config.
defaults: {
// Default module config.
defaults: {
initialDelay: 0,
lang: '',
location: '',
showLocation: true,
showIndex: true,
appendLocationNameToHeader: true,
updateInterval: 30, // every 30 minutes
animationSpeed: 1000,
token: '',
lang: '',
location: '',
showLocation: true,
showIndex: true,
appendLocationNameToHeader: true,
updateInterval: 30, // every 30 minutes
animationSpeed: 1000,
token: '',
apiBase: 'api.waqi.info/',
dataEndpoint: 'feed/',
},
},
notifications: {
DATA: 'AIR_QUALITY_DATA',
DATA_RESPONSE: 'AIR_QUALITY_DATA_RESPONSE',
},
start: function(){
start: function () {
const self = this
Log.info(`Starting module: ${this.name}`)
self.loaded = false
Expand All @@ -36,85 +36,84 @@ Module.register('MMM-AirQuality', {
setInterval(function () {
self.sendSocketNotification(self.notifications.DATA, self.config)
}, this.config.updateInterval * 60 * 1000 + this.config.initialDelay * 1000)
},
render: function(response){
let data = response.data;
this.data.value = data.aqi;
this.data.city = data.city.name;
this.loaded = true;
},
render: function (response) {
const data = response.data
this.data.value = data.aqi
this.data.city = data.city.name
this.loaded = true

if (data.aqi < 51) {
this.data.color = "#009966";
this.data.impact = 'Good';
} else if (data.aqi < 101) {
this.data.color = "#ffde33";
this.data.impact = 'Moderate';
} else if (data.aqi < 151) {
this.data.color = '#ff9933';
this.data.impact = 'Unhealty for Sensitive Groups';
} else if (data.aqi < 201) {
this.data.color = '#cc0033';
this.data.impact = 'Unhealthy';
} else if (data.aqi < 301) {
this.data.color = '#7e0023';
this.data.impact = 'Hazardous';
}
},
html: {
icon: '<i class="fa-solid fa-smog"></i>',
city: '<div class="xsmall">{0}</div>',
quality: '<div style="color: {0}">{1} {2}{3}</div>'
},
getScripts: function() {
return [
'//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.js',
'String.format.js'
];
},
getStyles: function() {
return ['https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css'];
},
if (data.aqi < 51) {
this.data.color = '#009966'
this.data.impact = 'Good'
} else if (data.aqi < 101) {
this.data.color = '#ffde33'
this.data.impact = 'Moderate'
} else if (data.aqi < 151) {
this.data.color = '#ff9933'
this.data.impact = 'Unhealty for Sensitive Groups'
} else if (data.aqi < 201) {
this.data.color = '#cc0033'
this.data.impact = 'Unhealthy'
} else if (data.aqi < 301) {
this.data.color = '#7e0023'
this.data.impact = 'Hazardous'
}
},
html: {
icon: '<i class="fa-solid fa-smog"></i>',
city: '<div class="xsmall">{0}</div>',
quality: '<div style="color: {0}">{1} {2}{3}</div>',
},
getScripts: function () {
return [
'//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.js',
'String.format.js',
]
},
getStyles: function () {
return ['https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css']
},
// Override getHeader method.
getHeader: function () {
var header = ""
if (this.data.header)
header += this.data.header;
let header = ''
if (this.data.header) { header += this.data.header }
if (this.config.appendLocationNameToHeader) {
if (header != "") {
header += " ";
if (header !== '') {
header += ' '
}
header += this.data.city;
header += this.data.city
}
return header
},
// Override dom generator.
getDom: function() {
var wrapper = document.createElement("div");
if (this.config.token === '') {
wrapper.innerHTML = "Please set the AQICN token for module: " + this.name + ". You can acquire one at <a href='https://aqicn.org/data-platform/token/'>https://aqicn.org/data-platform/token/</a>.";
wrapper.className = "dimmed light small";
return wrapper;
}
if (this.config.location === '') {
wrapper.innerHTML = "Please set the air quality index <i>location</i> in the config for module: " + this.name + ".";
wrapper.className = "dimmed light small";
return wrapper;
}
// Override dom generator.
getDom: function () {
const wrapper = document.createElement('div')
if (this.config.token === '') {
wrapper.innerHTML = 'Please set the AQICN token for module: ' + this.name + ". You can acquire one at <a href='https://aqicn.org/data-platform/token/'>https://aqicn.org/data-platform/token/</a>."
wrapper.className = 'dimmed light small'
return wrapper
}
if (this.config.location === '') {
wrapper.innerHTML = 'Please set the air quality index <i>location</i> in the config for module: ' + this.name + '.'
wrapper.className = 'dimmed light small'
return wrapper
}

if (!this.loaded) {
wrapper.innerHTML = "Loading air quality index ...";
wrapper.className = "dimmed light small";
return wrapper;
}
wrapper.innerHTML =
this.html.quality.format(
this.data.color,
this.html.icon,
this.data.impact,
(this.config.showIndex?' ('+this.data.value+')':''))+
(this.config.showLocation && !this.config.appendLocationNameToHeader?this.html.city.format(this.data.city):'');
return wrapper;
},
if (!this.loaded) {
wrapper.innerHTML = 'Loading air quality index ...'
wrapper.className = 'dimmed light small'
return wrapper
}
wrapper.innerHTML =
this.html.quality.format(
this.data.color,
this.html.icon,
this.data.impact,
(this.config.showIndex ? ' (' + this.data.value + ')' : '')) +
(this.config.showLocation && !this.config.appendLocationNameToHeader ? this.html.city.format(this.data.city) : '')
return wrapper
},
socketNotificationReceived: function (notification, payload) {
const self = this
Log.debug('received ' + notification)
Expand All @@ -123,11 +122,11 @@ Module.register('MMM-AirQuality', {
if (payload.status === 'OK') {
console.log('Data %o', payload.payloadReturn)
self.render(payload.payloadReturn)
self.updateDom(this.animationSpeed);
self.updateDom(this.animationSpeed)
} else {
console.log('DATA FAILED ' + payload.message)
}
break
}
},
});
})
18 changes: 9 additions & 9 deletions String.format.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// add string format method
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
// eslint-disable-next-line no-extend-native
String.prototype.format = function () {
const args = arguments
return this.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] !== 'undefined'
? args[number]
: match
})
}
}
16 changes: 8 additions & 8 deletions helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ module.exports = {
loadData: async function (config) {
const self = this
self.config = config
let url = `https://${self.config.apiBase}${self.config.dataEndpoint}${self.config.location}/?token=${this.config.token}`
console.log(`AirQuality loaded: ${url}`)
const url = `https://${self.config.apiBase}${self.config.dataEndpoint}${self.config.location}/?token=${this.config.token}`
console.log(`AirQuality loaded: ${url}`)

let result = await fetch(url)
.then(response => response.json())
const result = await fetch(url)
.then(response => response.json())

self.sendSocketNotification(self.notifications.DATA_RESPONSE, {
payloadReturn: result,
status: 'OK',
})
self.sendSocketNotification(self.notifications.DATA_RESPONSE, {
payloadReturn: result,
status: 'OK',
})
},
socketNotificationReceived: function (notification, payload) {
switch (notification) {
Expand Down
Loading

0 comments on commit 260cb29

Please sign in to comment.