Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions .eslintrc.js

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x, 18.x]
node-version: [22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@v5
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies (CI)
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ build/

# JetBrains Rider
**/.idea/**/*
**/Folder.DotSettings.user

# Added by Homey CLI
/.homeybuild/
16 changes: 4 additions & 12 deletions .homeycompose/app.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "no.runely.jslogic",
"version": "2.0.0",
"compatibility": ">=5.0.0",
"compatibility": ">=12.9.0",
"sdk": 3,
"brandColor": "#F0A100",
"name": {
Expand All @@ -10,9 +10,7 @@
"description": {
"en": "Use advanced logic through JavaScript"
},
"category": [
"tools"
],
"category": ["tools"],
"images": {
"large": "/assets/images/large.png",
"small": "/assets/images/small.png"
Expand All @@ -30,13 +28,7 @@
]
},
"tags": {
"en": [
"javascript",
"js",
"array",
"logic",
"advanced"
]
"en": ["javascript", "js", "array", "logic", "advanced"]
},
"bugs": {
"url": "https://github.com/runely/jslogic-homey/issues"
Expand Down Expand Up @@ -983,4 +975,4 @@
}
]
}
}
}
2 changes: 1 addition & 1 deletion .homeycompose/flow/conditions/is_random_true_false.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
"nl": "Dit zal willekeurig waar of onwaar zijn",
"no": "Denne vil tilfeldig være sann eller usann"
}
}
}
66 changes: 33 additions & 33 deletions .homeycompose/flow/conditions/value_too_long.json
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
{
"id": "value_too_long",
"title": {
"en": "Is value length !{{less|not less}} than",
"nl": "Is de lengte van de waarde !{{minder|niet minder}} dan",
"no": "Er tesktlengde !{{kortere|ikke kortere}} enn"
},
"titleFormatted": {
"en": "Is length of [[value]] !{{less|not less}} than [[maxLength]]",
"nl": "Is lengte van [[value]] !{{minder|niet minder}} dan [[maxLength]]",
"no": "Er tesktlengden på [[value]] !{{kortere|ikke kortere}} enn [[maxLength]]"
},
"args": [
{
"type": "text",
"name": "value",
"placeholder": {
"en": "Text value",
"nl": "Tekst waarde",
"no": "Tekst"
}
},
{
"type": "number",
"name": "maxLength",
"placeholder": {
"en": "Max length",
"nl": "Maximum lengte",
"no": "Makslengde"
}
}
]
}
{
"id": "value_too_long",
"title": {
"en": "Is value length !{{less|not less}} than",
"nl": "Is de lengte van de waarde !{{minder|niet minder}} dan",
"no": "Er tesktlengde !{{kortere|ikke kortere}} enn"
},
"titleFormatted": {
"en": "Is length of [[value]] !{{less|not less}} than [[maxLength]]",
"nl": "Is lengte van [[value]] !{{minder|niet minder}} dan [[maxLength]]",
"no": "Er tesktlengden på [[value]] !{{kortere|ikke kortere}} enn [[maxLength]]"
},
"args": [
{
"type": "text",
"name": "value",
"placeholder": {
"en": "Text value",
"nl": "Tekst waarde",
"no": "Tekst"
}
},
{
"type": "number",
"name": "maxLength",
"placeholder": {
"en": "Max length",
"nl": "Maximum lengte",
"no": "Makslengde"
}
}
]
}
3 changes: 2 additions & 1 deletion .homeyignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tests/
build/
types/
renovate.json
LICENSE
*.md
README*
*config.*
biome.json
*.user
2 changes: 1 addition & 1 deletion .homeyplugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
{
"id": "compose"
}
]
]
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
![ts](https://badgen.net/badge/Built%20With/TypeScript/blue)<br />
![image](https://img.shields.io/badge/eslint-3A33D1?style=for-the-badge&logo=eslint&logoColor=white)
![ts](https://badgen.net/badge/Built%20With/TypeScript/blue)
[![Formatted with Biome](https://img.shields.io/badge/Formatted_with-Biome-60a5fa?style=flat&logo=biome)](https://biomejs.dev/)

# JavaScript Logic

Expand Down Expand Up @@ -41,6 +41,9 @@ In the following conditions you can choose to use case sensitivity or not:

## Changelog

- 2.1.0
- JavaScript Logic is limited to only run on Homey Firmware >= 12.9.0, because this has Node.js 22 as runtime
- Switched from eslint to biome for development formatting and linting
- 2.0.0
- Migrated to TypeScript
- 1.6.2
Expand Down
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"_comment": "This file is generated. Please edit .homeycompose/app.json instead.",
"id": "no.runely.jslogic",
"version": "2.0.0",
"compatibility": ">=5.0.0",
"compatibility": ">=12.9.0",
"sdk": 3,
"brandColor": "#F0A100",
"name": {
Expand Down
93 changes: 50 additions & 43 deletions app.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,81 @@
import { ActionCard, ConditionCard, Timeouts, TriggerCard } from './types/types';
import ExtendedHomeyApp from './types/ExtendedHomeyApp';
import { HomeyManifest } from './types/HomeyManifest';

import Homey from 'homey';
import { Moment } from 'moment-timezone';

import type { Moment } from 'moment-timezone';
import formatMoment from './lib/format-moment';
import getNextTimeout from './lib/get-next-timeout-ms';
import moment from './lib/moment-datetime';
import ExtendedHomeyApp from './types/ExtendedHomeyApp';
import type { HomeyManifest } from './types/HomeyManifest';
import type { ActionCard, ConditionCard, Timeouts, TriggerCard } from './types/types';

const timeouts: Timeouts = {
dateMonthBecomes: null
};

class JSLogic extends ExtendedHomeyApp {
async onInit (): Promise<void> {
async onInit(): Promise<void> {
const manifest = Homey.manifest as HomeyManifest;
this.log(`${manifest.name.en} v${manifest.version} is running on ${this.homey.version}...`);

const { flow: { actions, conditions, triggers } } = manifest;

const {
flow: { actions, conditions, triggers }
} = manifest;

// create flow tokens
await this.homey.flow.createToken('formatted_date',
{ type: 'string', title: this.homey.__('flowTokens.formatted_date'), value: null });
await this.homey.flow.createToken('formatted_datetime',
{ type: 'string', title: this.homey.__('flowTokens.formatted_datetime'), value: null });
await this.homey.flow.createToken('formatted_date', {
type: 'string',
title: this.homey.__('flowTokens.formatted_date'),
value: null
});
await this.homey.flow.createToken('formatted_datetime', {
type: 'string',
title: this.homey.__('flowTokens.formatted_datetime'),
value: null
});

// timezone
const timezone = this.homey.clock.getTimezone();

// register action runListeners
actions.forEach(({ id }) => {
this.log('Adding runListener for action', id);
this.homey.flow.getActionCard(id)
.registerRunListener(async (args, _) => {
const { default: action } = await import(`./handlers/actions/${id}`) as { default: ActionCard };
return await action({
timezone,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
args, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
app: this
});
this.homey.flow.getActionCard(id).registerRunListener(async (args, _) => {
const { default: action } = (await import(`./handlers/actions/${id}`)) as { default: ActionCard };
return await action({
timezone,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
args, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
app: this
});
});
});

// register condition runListeners
conditions.forEach(({ id }) => {
this.log('Adding runListener for condition', id);
this.homey.flow.getConditionCard(id)
.registerRunListener(async (args, _) => {
const { default: condition } = await import(`./handlers/conditions/${id}`) as { default: ConditionCard };
return condition({
timezone,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
args, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
app: this
});
this.homey.flow.getConditionCard(id).registerRunListener(async (args, _) => {
const { default: condition } = (await import(`./handlers/conditions/${id}`)) as { default: ConditionCard };
return condition({
timezone,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
args, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
app: this
});
});
});

// register trigger runListeners
triggers.forEach(({ id }) => {
this.log('Adding runListener for trigger', id);
this.homey.flow.getTriggerCard(id)
.registerRunListener(async (args, state) => {
const { default: trigger } = await import(`./handlers/triggers/${id}`) as { default: TriggerCard };
return trigger({
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
args, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
state, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
app: this
});
this.homey.flow.getTriggerCard(id).registerRunListener(async (args, state) => {
const { default: trigger } = (await import(`./handlers/triggers/${id}`)) as { default: TriggerCard };
return trigger({
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
args, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
state, // Disabled because Homey.FlowCard.RunCallback specifies args and state as any
app: this
});
});
});

this.homey.on('unload', () => {
Expand All @@ -93,7 +96,9 @@ class JSLogic extends ExtendedHomeyApp {
const nextTimeout: number = getNextTimeout(timezone);

this.log('dateMonthBecomes: Triggering "date_month_becomes" card');
this.homey.flow.getTriggerCard('date_month_becomes').trigger(undefined, { date: now.get('date'), month: now.get('month') })
this.homey.flow
.getTriggerCard('date_month_becomes')
.trigger(undefined, { date: now.get('date'), month: now.get('month') })
.catch(error => this.logError('onInit/dateMonthBecomes: Failed when triggering triggerCard', error));

try {
Expand All @@ -107,7 +112,9 @@ class JSLogic extends ExtendedHomeyApp {
const nextTimeout = getNextTimeout(timezone);
timeouts.dateMonthBecomes = this.homey.setTimeout(dateMonthBecomes, nextTimeout);

this.log(`onInit/dateMonthBecomes: Next timeout ${formatMoment(moment({ timezone }).add(nextTimeout, 'milliseconds'))}`);
this.log(
`onInit/dateMonthBecomes: Next timeout ${formatMoment(moment({ timezone }).add(nextTimeout, 'milliseconds'))}`
);
}
}

Expand Down
Loading