@jakobgoerke/ac-infinity-client 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DeviceModeSettingsSchema = exports.DeviceSettingsSchema = exports.DeviceMode = exports.DeviceType = void 0;
3
+ exports.DeviceSettingsChangesSchema = exports.DeviceModeSettingsChangesSchema = exports.DeviceModeSettingsSchema = exports.DeviceSettingsSchema = exports.TemperatureUnit = exports.DeviceMode = exports.DeviceType = void 0;
4
4
  exports.encodeDeviceModeSettings = encodeDeviceModeSettings;
5
+ exports.encodeDeviceSettings = encodeDeviceSettings;
5
6
  const zod_1 = require("zod");
6
7
  var DeviceType;
7
8
  (function (DeviceType) {
9
+ DeviceType[DeviceType["NONE"] = 0] = "NONE";
8
10
  DeviceType[DeviceType["GROW_LIGHT"] = 1] = "GROW_LIGHT";
9
11
  DeviceType[DeviceType["HUMIDIFIER"] = 2] = "HUMIDIFIER";
10
12
  DeviceType[DeviceType["DEHUMIDIFIER"] = 3] = "DEHUMIDIFIER";
11
13
  DeviceType[DeviceType["HEATER"] = 4] = "HEATER";
12
14
  DeviceType[DeviceType["AIR_CONDITION"] = 5] = "AIR_CONDITION";
13
15
  DeviceType[DeviceType["FAN"] = 6] = "FAN";
16
+ DeviceType[DeviceType["PUMP"] = 8] = "PUMP";
17
+ DeviceType[DeviceType["WATER_PUMP"] = 9] = "WATER_PUMP";
18
+ DeviceType[DeviceType["CO2_GENERATOR"] = 10] = "CO2_GENERATOR";
19
+ DeviceType[DeviceType["WATER_COOLER"] = 13] = "WATER_COOLER";
20
+ DeviceType[DeviceType["WATER_HEATER"] = 14] = "WATER_HEATER";
14
21
  })(DeviceType || (exports.DeviceType = DeviceType = {}));
15
22
  var DeviceMode;
16
23
  (function (DeviceMode) {
@@ -23,6 +30,28 @@ var DeviceMode;
23
30
  DeviceMode[DeviceMode["SCHEDULE"] = 7] = "SCHEDULE";
24
31
  DeviceMode[DeviceMode["VPD"] = 8] = "VPD";
25
32
  })(DeviceMode || (exports.DeviceMode = DeviceMode = {}));
33
+ var TemperatureUnit;
34
+ (function (TemperatureUnit) {
35
+ TemperatureUnit[TemperatureUnit["FAHRENHEIT"] = 0] = "FAHRENHEIT";
36
+ TemperatureUnit[TemperatureUnit["CELSIUS"] = 1] = "CELSIUS";
37
+ })(TemperatureUnit || (exports.TemperatureUnit = TemperatureUnit = {}));
38
+ // the vendor uses this value for a schedule boundary that is not set
39
+ const SCHEDULE_DISABLED = 65535;
40
+ const celsiusToFahrenheit = (celsius) => Math.round((celsius * 9) / 5 + 32);
41
+ const fahrenheitToCelsius = (fahrenheit) => Math.round(((fahrenheit - 32) * 5) / 9);
42
+ const decodeScheduleTime = (minutes) => (minutes === SCHEDULE_DISABLED ? null : minutes);
43
+ const encodeScheduleTime = (minutes) => (minutes === null ? SCHEDULE_DISABLED : minutes);
44
+ const encodeFlag = (value) => (value === undefined ? undefined : Number(value));
45
+ const encodeTemperature = (value) => {
46
+ if (value?.celsius !== undefined) {
47
+ return { celsius: value.celsius, fahrenheit: celsiusToFahrenheit(value.celsius) };
48
+ }
49
+ if (value?.fahrenheit !== undefined) {
50
+ return { celsius: fahrenheitToCelsius(value.fahrenheit), fahrenheit: value.fahrenheit };
51
+ }
52
+ return { celsius: undefined, fahrenheit: undefined };
53
+ };
54
+ const compact = (value) => Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined));
26
55
  const DeviceBaseInputSchema = zod_1.z.object({
27
56
  devId: zod_1.z.string(),
28
57
  devMacAddr: zod_1.z.string().nullable(),
@@ -59,7 +88,7 @@ exports.DeviceSettingsSchema = DeviceBaseInputSchema.extend({
59
88
  devCh: zod_1.z.number(),
60
89
  devTt: zod_1.z.number(),
61
90
  devTh: zod_1.z.number(),
62
- devCompany: zod_1.z.number(),
91
+ devCompany: zod_1.z.enum(TemperatureUnit),
63
92
  devTth: zod_1.z.number(),
64
93
  vpdCth: zod_1.z.number(),
65
94
  vpdCt: zod_1.z.number(),
@@ -122,6 +151,30 @@ exports.DeviceSettingsSchema = DeviceBaseInputSchema.extend({
122
151
  matterSta: zod_1.z.unknown().nullable(),
123
152
  }).transform((v) => ({
124
153
  ...transformDeviceBase(v),
154
+ name: v.devName,
155
+ temperatureUnit: v.devCompany,
156
+ brightness: v.devLight,
157
+ backlight: v.backlightSwitch !== 0,
158
+ calibration: {
159
+ temperatureC: v.devCt,
160
+ temperatureF: v.devCth,
161
+ humidity: v.devCh,
162
+ leafTemperatureC: v.vpdCt,
163
+ leafTemperatureF: v.vpdCth,
164
+ },
165
+ transition: {
166
+ temperatureC: v.devTt,
167
+ temperatureF: v.devTth,
168
+ humidity: v.devTh,
169
+ vpd: v.vpdTransition,
170
+ },
171
+ buffer: {
172
+ enabled: v.isFlag !== 0,
173
+ temperatureC: v.devBt,
174
+ temperatureF: v.devBth,
175
+ humidity: v.devBh,
176
+ vpd: v.devBvpd,
177
+ },
125
178
  }));
126
179
  exports.DeviceModeSettingsSchema = DeviceBaseInputSchema.extend({
127
180
  acitveTimerOff: zod_1.z.number(),
@@ -178,9 +231,167 @@ exports.DeviceModeSettingsSchema = DeviceBaseInputSchema.extend({
178
231
  waterTempLowValueF: zod_1.z.number(),
179
232
  }).transform((v) => ({
180
233
  ...transformDeviceBase(v),
234
+ /** seconds left until the current timer, cycle or schedule step switches */
235
+ remainingTime: v.surplus,
236
+ /** durations in seconds */
237
+ timer: {
238
+ toOn: v.acitveTimerOn,
239
+ toOff: v.acitveTimerOff,
240
+ },
241
+ /** durations in seconds */
242
+ cycle: {
243
+ on: v.activeCycleOn,
244
+ off: v.activeCycleOff,
245
+ },
246
+ /** minutes after midnight, null when not set */
247
+ schedule: {
248
+ start: decodeScheduleTime(v.schedStartTime),
249
+ end: decodeScheduleTime(v.schedEndtTime),
250
+ },
251
+ auto: {
252
+ targetMode: v.settingMode !== 0,
253
+ highTemperature: { enabled: v.activeHt !== 0, celsius: v.devHt, fahrenheit: v.devHtf },
254
+ lowTemperature: { enabled: v.activeLt !== 0, celsius: v.devLt, fahrenheit: v.devLtf },
255
+ highHumidity: { enabled: v.activeHh !== 0, value: v.devHh },
256
+ lowHumidity: { enabled: v.activeLh !== 0, value: v.devLh },
257
+ targetTemperature: { enabled: v.targetTSwitch !== 0, celsius: v.targetTemp, fahrenheit: v.targetTempF },
258
+ targetHumidity: { enabled: v.targetHumiSwitch !== 0, value: v.targetHumi },
259
+ },
260
+ /** values in kPa */
261
+ vpd: {
262
+ targetMode: v.vpdSettingMode !== 0,
263
+ high: { enabled: v.activeHtVpd !== 0, value: v.activeHtVpdNums / 10 },
264
+ low: { enabled: v.activeLtVpd !== 0, value: v.activeLtVpdNums / 10 },
265
+ target: { enabled: v.targetVpdSwitch !== 0, value: v.targetVpd / 10 },
266
+ },
181
267
  }));
268
+ const LevelSchema = zod_1.z.number().int().min(0).max(10);
269
+ const DurationSchema = zod_1.z.number().int().nonnegative();
270
+ const ScheduleTimeSchema = zod_1.z.number().int().min(0).max(1439).nullable();
271
+ const TemperatureTriggerChangesSchema = zod_1.z
272
+ .object({
273
+ enabled: zod_1.z.boolean(),
274
+ celsius: zod_1.z.number().int().min(0).max(90),
275
+ fahrenheit: zod_1.z.number().int().min(32).max(194),
276
+ })
277
+ .partial()
278
+ .refine((v) => v.celsius === undefined || v.fahrenheit === undefined, { message: 'Provide either celsius or fahrenheit, not both' });
279
+ const HumidityTriggerChangesSchema = zod_1.z
280
+ .object({
281
+ enabled: zod_1.z.boolean(),
282
+ value: zod_1.z.number().int().min(0).max(100),
283
+ })
284
+ .partial();
285
+ const VpdTriggerChangesSchema = zod_1.z
286
+ .object({
287
+ enabled: zod_1.z.boolean(),
288
+ value: zod_1.z.number().min(0).max(9.9),
289
+ })
290
+ .partial();
291
+ exports.DeviceModeSettingsChangesSchema = zod_1.z
292
+ .object({
293
+ mode: zod_1.z.enum(DeviceMode),
294
+ levelWhileOn: LevelSchema,
295
+ levelWhileOff: LevelSchema,
296
+ timer: zod_1.z.object({ toOn: DurationSchema, toOff: DurationSchema }).partial(),
297
+ cycle: zod_1.z.object({ on: DurationSchema, off: DurationSchema }).partial(),
298
+ schedule: zod_1.z.object({ start: ScheduleTimeSchema, end: ScheduleTimeSchema }).partial(),
299
+ auto: zod_1.z
300
+ .object({
301
+ targetMode: zod_1.z.boolean(),
302
+ highTemperature: TemperatureTriggerChangesSchema,
303
+ lowTemperature: TemperatureTriggerChangesSchema,
304
+ highHumidity: HumidityTriggerChangesSchema,
305
+ lowHumidity: HumidityTriggerChangesSchema,
306
+ targetTemperature: TemperatureTriggerChangesSchema,
307
+ targetHumidity: HumidityTriggerChangesSchema,
308
+ })
309
+ .partial(),
310
+ vpd: zod_1.z
311
+ .object({
312
+ targetMode: zod_1.z.boolean(),
313
+ high: VpdTriggerChangesSchema,
314
+ low: VpdTriggerChangesSchema,
315
+ target: VpdTriggerChangesSchema,
316
+ })
317
+ .partial(),
318
+ })
319
+ .partial()
320
+ .transform(({ mode, levelWhileOn, levelWhileOff, timer, cycle, schedule, auto, vpd }) => {
321
+ const highTemperature = encodeTemperature(auto?.highTemperature);
322
+ const lowTemperature = encodeTemperature(auto?.lowTemperature);
323
+ const targetTemperature = encodeTemperature(auto?.targetTemperature);
324
+ const encodeVpd = (value) => (value === undefined ? undefined : Math.round(value * 10));
325
+ return compact({
326
+ atType: mode,
327
+ onSpead: levelWhileOn,
328
+ offSpead: levelWhileOff,
329
+ acitveTimerOn: timer?.toOn,
330
+ acitveTimerOff: timer?.toOff,
331
+ activeCycleOn: cycle?.on,
332
+ activeCycleOff: cycle?.off,
333
+ schedStartTime: encodeScheduleTime(schedule?.start),
334
+ schedEndtTime: encodeScheduleTime(schedule?.end),
335
+ settingMode: encodeFlag(auto?.targetMode),
336
+ activeHt: encodeFlag(auto?.highTemperature?.enabled),
337
+ devHt: highTemperature.celsius,
338
+ devHtf: highTemperature.fahrenheit,
339
+ activeLt: encodeFlag(auto?.lowTemperature?.enabled),
340
+ devLt: lowTemperature.celsius,
341
+ devLtf: lowTemperature.fahrenheit,
342
+ activeHh: encodeFlag(auto?.highHumidity?.enabled),
343
+ devHh: auto?.highHumidity?.value,
344
+ activeLh: encodeFlag(auto?.lowHumidity?.enabled),
345
+ devLh: auto?.lowHumidity?.value,
346
+ targetTSwitch: encodeFlag(auto?.targetTemperature?.enabled),
347
+ targetTemp: targetTemperature.celsius,
348
+ targetTempF: targetTemperature.fahrenheit,
349
+ targetHumiSwitch: encodeFlag(auto?.targetHumidity?.enabled),
350
+ targetHumi: auto?.targetHumidity?.value,
351
+ vpdSettingMode: encodeFlag(vpd?.targetMode),
352
+ activeHtVpd: encodeFlag(vpd?.high?.enabled),
353
+ activeHtVpdNums: encodeVpd(vpd?.high?.value),
354
+ activeLtVpd: encodeFlag(vpd?.low?.enabled),
355
+ activeLtVpdNums: encodeVpd(vpd?.low?.value),
356
+ targetVpdSwitch: encodeFlag(vpd?.target?.enabled),
357
+ targetVpd: encodeVpd(vpd?.target?.value),
358
+ });
359
+ });
360
+ exports.DeviceSettingsChangesSchema = zod_1.z
361
+ .object({
362
+ name: zod_1.z.string().min(1),
363
+ temperatureUnit: zod_1.z.enum(TemperatureUnit),
364
+ brightness: zod_1.z.number().int().nonnegative(),
365
+ backlight: zod_1.z.boolean(),
366
+ calibration: zod_1.z
367
+ .object({
368
+ temperatureC: zod_1.z.number().int(),
369
+ temperatureF: zod_1.z.number().int(),
370
+ humidity: zod_1.z.number().int(),
371
+ })
372
+ .partial()
373
+ .refine((v) => v.temperatureC === undefined || v.temperatureF === undefined, {
374
+ message: 'Provide either temperatureC or temperatureF, not both',
375
+ }),
376
+ })
377
+ .partial()
378
+ .transform(({ name, temperatureUnit, brightness, backlight, calibration }) => {
379
+ // the fahrenheit calibration is kept at twice the celsius one
380
+ const calibrationC = calibration?.temperatureF !== undefined ? Math.trunc(calibration.temperatureF / 2) : calibration?.temperatureC;
381
+ const calibrationF = calibration?.temperatureC !== undefined ? calibration.temperatureC * 2 : calibration?.temperatureF;
382
+ return compact({
383
+ devName: name,
384
+ devCompany: temperatureUnit,
385
+ devLight: brightness,
386
+ backlightSwitch: encodeFlag(backlight),
387
+ devCt: calibrationC,
388
+ devCth: calibrationF,
389
+ devCh: calibration?.humidity,
390
+ });
391
+ });
182
392
  function encodeDeviceModeSettings(settings) {
183
- return {
184
- onSpead: settings.levelWhileOn,
185
- };
393
+ return exports.DeviceModeSettingsChangesSchema.parse(settings);
394
+ }
395
+ function encodeDeviceSettings(settings) {
396
+ return exports.DeviceSettingsChangesSchema.parse(settings);
186
397
  }
@@ -1,7 +1,7 @@
1
- export type { Controller, ControllerDeviceInfo, ControllerPort } from './Controller';
2
- export { ControllerDeviceType, ControllerSchema } from './Controller';
3
- export type { DeviceModeSettings, DeviceModeSettingsInput, DeviceSettings } from './Device';
4
- export { DeviceMode, DeviceModeSettingsSchema, DeviceSettingsSchema, DeviceType, encodeDeviceModeSettings } from './Device';
1
+ export type { Controller, ControllerDeviceInfo, ControllerPort, ControllerSensor } from './Controller';
2
+ export { ControllerDeviceType, ControllerSchema, SensorType } from './Controller';
3
+ export type { DeviceModeSettings, DeviceModeSettingsChanges, DeviceModeSettingsInput, DeviceSettings, DeviceSettingsChanges, DeviceSettingsInput, } from './Device';
4
+ export { DeviceMode, DeviceModeSettingsChangesSchema, DeviceModeSettingsSchema, DeviceSettingsChangesSchema, DeviceSettingsSchema, DeviceType, encodeDeviceModeSettings, encodeDeviceSettings, TemperatureUnit, } from './Device';
5
5
  export type { User } from './User';
6
6
  export { UserSchema } from './User';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAC5H,YAAY,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAClF,YAAY,EACV,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,UAAU,EACV,+BAA+B,EAC/B,wBAAwB,EACxB,2BAA2B,EAC3B,oBAAoB,EACpB,UAAU,EACV,wBAAwB,EACxB,oBAAoB,EACpB,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC"}
@@ -1,14 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UserSchema = exports.encodeDeviceModeSettings = exports.DeviceType = exports.DeviceSettingsSchema = exports.DeviceModeSettingsSchema = exports.DeviceMode = exports.ControllerSchema = exports.ControllerDeviceType = void 0;
3
+ exports.UserSchema = exports.TemperatureUnit = exports.encodeDeviceSettings = exports.encodeDeviceModeSettings = exports.DeviceType = exports.DeviceSettingsSchema = exports.DeviceSettingsChangesSchema = exports.DeviceModeSettingsSchema = exports.DeviceModeSettingsChangesSchema = exports.DeviceMode = exports.SensorType = exports.ControllerSchema = exports.ControllerDeviceType = void 0;
4
4
  var Controller_1 = require("./Controller");
5
5
  Object.defineProperty(exports, "ControllerDeviceType", { enumerable: true, get: function () { return Controller_1.ControllerDeviceType; } });
6
6
  Object.defineProperty(exports, "ControllerSchema", { enumerable: true, get: function () { return Controller_1.ControllerSchema; } });
7
+ Object.defineProperty(exports, "SensorType", { enumerable: true, get: function () { return Controller_1.SensorType; } });
7
8
  var Device_1 = require("./Device");
8
9
  Object.defineProperty(exports, "DeviceMode", { enumerable: true, get: function () { return Device_1.DeviceMode; } });
10
+ Object.defineProperty(exports, "DeviceModeSettingsChangesSchema", { enumerable: true, get: function () { return Device_1.DeviceModeSettingsChangesSchema; } });
9
11
  Object.defineProperty(exports, "DeviceModeSettingsSchema", { enumerable: true, get: function () { return Device_1.DeviceModeSettingsSchema; } });
12
+ Object.defineProperty(exports, "DeviceSettingsChangesSchema", { enumerable: true, get: function () { return Device_1.DeviceSettingsChangesSchema; } });
10
13
  Object.defineProperty(exports, "DeviceSettingsSchema", { enumerable: true, get: function () { return Device_1.DeviceSettingsSchema; } });
11
14
  Object.defineProperty(exports, "DeviceType", { enumerable: true, get: function () { return Device_1.DeviceType; } });
12
15
  Object.defineProperty(exports, "encodeDeviceModeSettings", { enumerable: true, get: function () { return Device_1.encodeDeviceModeSettings; } });
16
+ Object.defineProperty(exports, "encodeDeviceSettings", { enumerable: true, get: function () { return Device_1.encodeDeviceSettings; } });
17
+ Object.defineProperty(exports, "TemperatureUnit", { enumerable: true, get: function () { return Device_1.TemperatureUnit; } });
13
18
  var User_1 = require("./User");
14
19
  Object.defineProperty(exports, "UserSchema", { enumerable: true, get: function () { return User_1.UserSchema; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jakobgoerke/ac-infinity-client",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "main": "./build/src",
5
5
  "types": "./build/src/index.d.ts",
6
6
  "repository": "git@github.com:jakobgoerke/ac-infinity-client.git",
@@ -11,20 +11,20 @@
11
11
  "build/src/**"
12
12
  ],
13
13
  "dependencies": {
14
- "axios": "1.13.5",
15
- "zod": "4.3.6"
14
+ "axios": "1.20.0",
15
+ "zod": "4.6.7"
16
16
  },
17
17
  "devDependencies": {
18
- "@biomejs/biome": "2.4.4",
19
- "@jest/globals": "30.2.0",
20
- "@tsconfig/node24": "24.0.4",
18
+ "@biomejs/biome": "2.6.2",
19
+ "@jest/globals": "30.5.2",
20
+ "@tsconfig/node24": "24.0.5",
21
21
  "@types/jest": "30.0.0",
22
- "@types/node": "25.3.0",
23
- "jest": "30.2.0",
22
+ "@types/node": "24.19.2",
23
+ "jest": "30.5.2",
24
24
  "rimraf": "6.1.3",
25
- "ts-jest": "29.4.6",
25
+ "ts-jest": "29.4.15",
26
26
  "ts-node": "10.9.2",
27
- "typescript": "5.9.3"
27
+ "typescript": "6.0.3"
28
28
  },
29
29
  "scripts": {
30
30
  "build": "rimraf build && tsc -p .",
@@ -33,5 +33,9 @@
33
33
  "coverage": "jest --coverage",
34
34
  "lint": "biome check"
35
35
  },
36
- "packageManager": "yarn@4.12.0"
36
+ "packageManager": "yarn@4.12.0",
37
+ "publishConfig": {
38
+ "access": "public",
39
+ "provenance": true
40
+ }
37
41
  }