hoffmation-base 3.0.0-beta.0 → 3.0.0-beta.10
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.
- package/README.md +34 -8
- package/lib/models/action/handleChangeAction.d.ts +12 -0
- package/lib/models/action/handleChangeAction.js +15 -0
- package/lib/models/action/index.d.ts +1 -0
- package/lib/models/action/index.js +3 -1
- package/lib/models/command/commandType.d.ts +1 -0
- package/lib/models/command/commandType.js +1 -0
- package/lib/models/deviceSettings/dachsSettings.d.ts +8 -0
- package/lib/models/deviceSettings/dachsSettings.js +12 -1
- package/lib/models/deviceSettings/heaterSettings.d.ts +4 -0
- package/lib/models/deviceSettings/heaterSettings.js +14 -8
- package/lib/server/devices/baseDeviceInterfaces/iHandleSensor.d.ts +6 -0
- package/lib/server/devices/baseDeviceInterfaces/iHeater.d.ts +12 -15
- package/lib/server/devices/baseDeviceInterfaces/index.d.ts +1 -0
- package/lib/server/devices/baseDeviceInterfaces/index.js +1 -0
- package/lib/server/devices/dachs/dachs.d.ts +3 -1
- package/lib/server/devices/dachs/dachs.js +19 -5
- package/lib/server/devices/dachs/lib/dachsHttpClient.js +4 -0
- package/lib/server/devices/device-cluster.js +6 -0
- package/lib/server/devices/deviceType.d.ts +1 -0
- package/lib/server/devices/deviceType.js +1 -0
- package/lib/server/devices/devices.js +3 -0
- package/lib/server/devices/groups/Window.d.ts +7 -1
- package/lib/server/devices/groups/Window.js +15 -1
- package/lib/server/devices/groups/heatGroup.js +22 -5
- package/lib/server/devices/groups/windowGroup.d.ts +11 -1
- package/lib/server/devices/groups/windowGroup.js +18 -0
- package/lib/server/devices/hmIPDevices/hmIpGriff.d.ts +3 -0
- package/lib/server/devices/hmIPDevices/hmIpGriff.js +4 -0
- package/lib/server/devices/hmIPDevices/hmIpHeizgruppe.d.ts +7 -1
- package/lib/server/devices/hmIPDevices/hmIpHeizgruppe.js +24 -0
- package/lib/server/devices/sharedFunctions/handleSensor.d.ts +3 -2
- package/lib/server/devices/sharedFunctions/handleSensor.js +8 -0
- package/lib/server/devices/sharedFunctions/temperatureSensor.d.ts +6 -0
- package/lib/server/devices/sharedFunctions/temperatureSensor.js +12 -2
- package/lib/server/devices/shelly/shellyTrv.d.ts +16 -5
- package/lib/server/devices/shelly/shellyTrv.js +40 -6
- package/lib/server/devices/zigbee/BaseDevices/zigbeeHeater.d.ts +15 -5
- package/lib/server/devices/zigbee/BaseDevices/zigbeeHeater.js +45 -14
- package/lib/server/devices/zigbee/BaseDevices/zigbeeWindowHandle.d.ts +3 -0
- package/lib/server/devices/zigbee/BaseDevices/zigbeeWindowHandle.js +4 -0
- package/lib/server/devices/zigbee/index.d.ts +1 -0
- package/lib/server/devices/zigbee/index.js +3 -0
- package/lib/server/devices/zigbee/zigbeeEuroHeater.d.ts +1 -1
- package/lib/server/devices/zigbee/zigbeeEuroHeater.js +5 -5
- package/lib/server/devices/zigbee/zigbeeSodaHandle.d.ts +4 -0
- package/lib/server/devices/zigbee/zigbeeSodaHandle.js +7 -2
- package/lib/server/devices/zigbee/zigbeeTuyaMotion.d.ts +7 -0
- package/lib/server/devices/zigbee/zigbeeTuyaMotion.js +18 -0
- package/lib/server/devices/zigbee/zigbeeTuyaValve.d.ts +2 -1
- package/lib/server/devices/zigbee/zigbeeTuyaValve.js +7 -4
- package/lib/server/services/Sonos/mp3-server.js +6 -0
- package/lib/server/services/Telegram/telegram-service.js +9 -0
- package/lib/server/services/dbo/postgreSqlPersist.js +90 -66
- package/lib/server/services/https-service.js +3 -0
- package/lib/server/services/weather/weather-service.js +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,34 +1,60 @@
|
|
|
1
1
|
# Hoffmation-Base
|
|
2
|
+
|
|
2
3
|
[](https://deepsource.io/gh/theimo1221/Hoffmation-Base/?ref=repository-badge)
|
|
3
4
|
|
|
4
5
|
A home automation library specialized for Zigbee and Homematic IP devices in combination with ioBroker.
|
|
6
|
+
|
|
5
7
|
## What does it do?
|
|
6
|
-
This project serves as library for home automation projects. It provides services, models and utilities necessary to interact with rooms and smart devices via iobroker, but also to connect them to other services for textual/audio/visual notifications or really just any code or service you want the devices to connect to.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
This project serves as library for home automation projects. It provides services, models and utilities necessary to
|
|
10
|
+
interact with rooms and smart devices via iobroker, but also to connect them to other services for textual/audio/visual
|
|
11
|
+
notifications or really just any code or service you want the devices to connect to.
|
|
12
|
+
|
|
13
|
+
Built on other open source projects that take care of the technical level, this project is made to provide a tool for
|
|
14
|
+
the coding on the logical level. It is built as base to write automation code independent of the ioBroker user interface
|
|
15
|
+
and currently provides support for the interaction with **devices** specified in [
|
|
16
|
+
`src/server/devices`](src/server/devices) and **services** that can be found in [
|
|
17
|
+
`src/server/services`](src/server/devices).
|
|
9
18
|
|
|
10
19
|
Those include, but are not limited to:
|
|
11
20
|
|
|
12
|
-
- **Devices**: Motion/Presence sensors, window handles, heating elements, lamps and dimmers, shutters, door contact
|
|
21
|
+
- **Devices**: Motion/Presence sensors, window handles, heating elements, lamps and dimmers, shutters, door contact
|
|
22
|
+
sensors, physical buttons/switches, power sockets
|
|
13
23
|
- **Services**: Interaction service for a telegram bot, weather, sonos control, waste calendar
|
|
14
24
|
|
|
25
|
+
## Ecosystem Overview
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
15
29
|
## How can I use it?
|
|
16
|
-
This library *can* be used in conjunction with or as addition to own base projects, but it's intended to be used with the configuration project [Hoffmation-Express](https://github.com/theimo1221/Hoffmation-Express) which uses this library via a [npm package](https://www.npmjs.com/package/hoffmation-base).
|
|
17
30
|
|
|
18
|
-
|
|
31
|
+
This library *can* be used in conjunction with or as addition to own base projects, but it's intended to be used with
|
|
32
|
+
the configuration project [Hoffmation-Express](https://github.com/theimo1221/Hoffmation-Express) which uses this library
|
|
33
|
+
via a [npm package](https://www.npmjs.com/package/hoffmation-base).
|
|
34
|
+
|
|
35
|
+
Whether you use it with Hoffmation-Express or with your own controller code, make sure you pass a valid config file (
|
|
36
|
+
see [`src/server/config/private`](src/server/config/private) for an example) and a valid ioBroker device tree (you can
|
|
37
|
+
find more information about that in the Hoffmation-Express project).
|
|
19
38
|
|
|
20
39
|
### Base requirements
|
|
40
|
+
|
|
21
41
|
In order to get the library running correctly, the following requirements should be met:
|
|
42
|
+
|
|
22
43
|
* You use ioBroker for all devices that you want to control or read from
|
|
23
44
|
Make sure you got the [socket.io](https://github.com/ioBroker/ioBroker.socketio) adapter installed
|
|
24
45
|
* You use devices that are supported or are able to use one of the supported devices as base for yours.
|
|
25
|
-
(If you use a Zigbee or Homematic IP device that is not currently supported, don't hesitate to create a pull request
|
|
46
|
+
(If you use a Zigbee or Homematic IP device that is not currently supported, don't hesitate to create a pull request
|
|
47
|
+
and add it!)
|
|
26
48
|
* You have a unix-based or windows device for the software you want to run this library with.
|
|
27
49
|
|
|
28
50
|
### Build
|
|
51
|
+
|
|
29
52
|
To build the library, make sure [Node.js](https://nodejs.org/en/download/) is installed.
|
|
30
53
|
Then, just run `npm run build`.
|
|
31
54
|
|
|
32
55
|
## Why would I use it?
|
|
33
|
-
|
|
34
|
-
|
|
56
|
+
|
|
57
|
+
Even if it looks simple at first, automating your entire home with a user interface can sometimes be more difficult than
|
|
58
|
+
just *coding* your home.
|
|
59
|
+
Especially if you have a lot of specialized requirements that you want to satisfy, it can be simpler to just code your
|
|
60
|
+
own rules and interfaces than to rely on user interfaces to do it for you.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseAction } from './baseAction';
|
|
2
|
+
import { CommandType } from '../command';
|
|
3
|
+
import { iHandleSensor } from '../../server';
|
|
4
|
+
export declare class HandleChangeAction extends BaseAction {
|
|
5
|
+
/** @inheritDoc */
|
|
6
|
+
type: CommandType;
|
|
7
|
+
/**
|
|
8
|
+
* The window-handle that triggered the action
|
|
9
|
+
*/
|
|
10
|
+
readonly handle: iHandleSensor;
|
|
11
|
+
constructor(handle: iHandleSensor);
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HandleChangeAction = void 0;
|
|
4
|
+
const baseAction_1 = require("./baseAction");
|
|
5
|
+
const command_1 = require("../command");
|
|
6
|
+
const server_1 = require("../../server");
|
|
7
|
+
class HandleChangeAction extends baseAction_1.BaseAction {
|
|
8
|
+
constructor(handle) {
|
|
9
|
+
super(undefined, `${handle.customName} ${handle.position === server_1.WindowPosition.closed ? 'opened' : 'closed'}`);
|
|
10
|
+
/** @inheritDoc */
|
|
11
|
+
this.type = command_1.CommandType.HandleChangedAction;
|
|
12
|
+
this.handle = handle;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.HandleChangeAction = HandleChangeAction;
|
|
@@ -8,3 +8,4 @@ export * from './temperatureSensorChangeAction';
|
|
|
8
8
|
export { ActuatorChangeAction } from './actuatorChangeAction';
|
|
9
9
|
export { BatteryLevelChangeAction } from './batteryLevelChangeAction';
|
|
10
10
|
export { PresenceGroupAnyMovementAction } from './presenceGroupAnyMovementAction';
|
|
11
|
+
export { HandleChangeAction } from './handleChangeAction';
|
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.PresenceGroupAnyMovementAction = exports.BatteryLevelChangeAction = exports.ActuatorChangeAction = exports.BaseAction = void 0;
|
|
17
|
+
exports.HandleChangeAction = exports.PresenceGroupAnyMovementAction = exports.BatteryLevelChangeAction = exports.ActuatorChangeAction = exports.BaseAction = void 0;
|
|
18
18
|
var baseAction_1 = require("./baseAction");
|
|
19
19
|
Object.defineProperty(exports, "BaseAction", { enumerable: true, get: function () { return baseAction_1.BaseAction; } });
|
|
20
20
|
__exportStar(require("./humiditySensorChangeAction"), exports);
|
|
@@ -29,3 +29,5 @@ var batteryLevelChangeAction_1 = require("./batteryLevelChangeAction");
|
|
|
29
29
|
Object.defineProperty(exports, "BatteryLevelChangeAction", { enumerable: true, get: function () { return batteryLevelChangeAction_1.BatteryLevelChangeAction; } });
|
|
30
30
|
var presenceGroupAnyMovementAction_1 = require("./presenceGroupAnyMovementAction");
|
|
31
31
|
Object.defineProperty(exports, "PresenceGroupAnyMovementAction", { enumerable: true, get: function () { return presenceGroupAnyMovementAction_1.PresenceGroupAnyMovementAction; } });
|
|
32
|
+
var handleChangeAction_1 = require("./handleChangeAction");
|
|
33
|
+
Object.defineProperty(exports, "HandleChangeAction", { enumerable: true, get: function () { return handleChangeAction_1.HandleChangeAction; } });
|
|
@@ -28,6 +28,7 @@ export declare enum CommandType {
|
|
|
28
28
|
ShutterSunriseUpCommand = "ShutterSunriseUpCommand",
|
|
29
29
|
SunsetDownCommand = "SunsetDownCommand",
|
|
30
30
|
TemperatureSensorChangeAction = "TemperatureSensorChangeAction",
|
|
31
|
+
HandleChangedAction = "HandleChangedAction",
|
|
31
32
|
WindowRestoreDesiredPositionCommand = "WindowRestoreDesiredPositionCommand",
|
|
32
33
|
WindowSetDesiredPositionCommand = "WindowSetDesiredPositionCommand",
|
|
33
34
|
WindowSetRolloByWeatherStatusCommand = "WindowSetRolloByWeatherStatusCommand",
|
|
@@ -32,6 +32,7 @@ var CommandType;
|
|
|
32
32
|
CommandType["ShutterSunriseUpCommand"] = "ShutterSunriseUpCommand";
|
|
33
33
|
CommandType["SunsetDownCommand"] = "SunsetDownCommand";
|
|
34
34
|
CommandType["TemperatureSensorChangeAction"] = "TemperatureSensorChangeAction";
|
|
35
|
+
CommandType["HandleChangedAction"] = "HandleChangedAction";
|
|
35
36
|
CommandType["WindowRestoreDesiredPositionCommand"] = "WindowRestoreDesiredPositionCommand";
|
|
36
37
|
CommandType["WindowSetDesiredPositionCommand"] = "WindowSetDesiredPositionCommand";
|
|
37
38
|
CommandType["WindowSetRolloByWeatherStatusCommand"] = "WindowSetRolloByWeatherStatusCommand";
|
|
@@ -37,6 +37,14 @@ export declare class DachsDeviceSettings extends ActuatorSettings {
|
|
|
37
37
|
* Defines the desired minimum temperature for warm water.
|
|
38
38
|
*/
|
|
39
39
|
warmWaterDesiredMinTemp: number;
|
|
40
|
+
/**
|
|
41
|
+
* Defines the desired minimum temperature for heat storage during winter.
|
|
42
|
+
*/
|
|
43
|
+
winterMinimumHeatStorageTemp: number;
|
|
44
|
+
/**
|
|
45
|
+
* Defines the desired minimum temperature for heat storage during winter.
|
|
46
|
+
*/
|
|
47
|
+
winterMinimumPreNightHeatStorageTemp: number;
|
|
40
48
|
fromPartialObject(data: Partial<DachsDeviceSettings>): void;
|
|
41
49
|
protected toJSON(): Partial<DachsDeviceSettings>;
|
|
42
50
|
}
|
|
@@ -43,9 +43,17 @@ class DachsDeviceSettings extends actuatorSettings_1.ActuatorSettings {
|
|
|
43
43
|
* Defines the desired minimum temperature for warm water.
|
|
44
44
|
*/
|
|
45
45
|
this.warmWaterDesiredMinTemp = 45;
|
|
46
|
+
/**
|
|
47
|
+
* Defines the desired minimum temperature for heat storage during winter.
|
|
48
|
+
*/
|
|
49
|
+
this.winterMinimumHeatStorageTemp = 55;
|
|
50
|
+
/**
|
|
51
|
+
* Defines the desired minimum temperature for heat storage during winter.
|
|
52
|
+
*/
|
|
53
|
+
this.winterMinimumPreNightHeatStorageTemp = 65;
|
|
46
54
|
}
|
|
47
55
|
fromPartialObject(data) {
|
|
48
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
56
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
49
57
|
this.refreshIntervalTime = (_a = data.refreshIntervalTime) !== null && _a !== void 0 ? _a : this.refreshIntervalTime;
|
|
50
58
|
this.batteryLevelBeforeNightTurnOnThreshold =
|
|
51
59
|
(_b = data.batteryLevelBeforeNightTurnOnThreshold) !== null && _b !== void 0 ? _b : this.batteryLevelBeforeNightTurnOnThreshold;
|
|
@@ -55,6 +63,9 @@ class DachsDeviceSettings extends actuatorSettings_1.ActuatorSettings {
|
|
|
55
63
|
(_e = data.batteryLevelPreventStartThreshold) !== null && _e !== void 0 ? _e : this.batteryLevelPreventStartThreshold;
|
|
56
64
|
this.batteryLevelAllowStartThreshold = (_f = data.batteryLevelAllowStartThreshold) !== null && _f !== void 0 ? _f : this.batteryLevelAllowStartThreshold;
|
|
57
65
|
this.warmWaterDesiredMinTemp = (_g = data.warmWaterDesiredMinTemp) !== null && _g !== void 0 ? _g : this.warmWaterDesiredMinTemp;
|
|
66
|
+
this.winterMinimumHeatStorageTemp = (_h = data.winterMinimumHeatStorageTemp) !== null && _h !== void 0 ? _h : this.winterMinimumHeatStorageTemp;
|
|
67
|
+
this.winterMinimumPreNightHeatStorageTemp =
|
|
68
|
+
(_j = data.winterMinimumPreNightHeatStorageTemp) !== null && _j !== void 0 ? _j : this.winterMinimumPreNightHeatStorageTemp;
|
|
58
69
|
super.fromPartialObject(data);
|
|
59
70
|
}
|
|
60
71
|
toJSON() {
|
|
@@ -10,6 +10,10 @@ export declare class HeaterSettings extends DeviceSettings {
|
|
|
10
10
|
* @default true
|
|
11
11
|
*/
|
|
12
12
|
useOwnTemperatur: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether this devices temperature measurement should be included in the room temperature calculation.
|
|
15
|
+
*/
|
|
16
|
+
useOwnTemperatureForRoomTemperature: boolean;
|
|
13
17
|
/**
|
|
14
18
|
* Whether this device should be controlled using only valve position
|
|
15
19
|
* @default false
|
|
@@ -16,6 +16,10 @@ class HeaterSettings extends deviceSettings_1.DeviceSettings {
|
|
|
16
16
|
* @default true
|
|
17
17
|
*/
|
|
18
18
|
this.useOwnTemperatur = true;
|
|
19
|
+
/**
|
|
20
|
+
* Whether this devices temperature measurement should be included in the room temperature calculation.
|
|
21
|
+
*/
|
|
22
|
+
this.useOwnTemperatureForRoomTemperature = true;
|
|
19
23
|
/**
|
|
20
24
|
* Whether this device should be controlled using only valve position
|
|
21
25
|
* @default false
|
|
@@ -55,16 +59,18 @@ class HeaterSettings extends deviceSettings_1.DeviceSettings {
|
|
|
55
59
|
this.manualDisabled = false;
|
|
56
60
|
}
|
|
57
61
|
fromPartialObject(data) {
|
|
58
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
62
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
59
63
|
this.automaticMode = (_a = data.automaticMode) !== null && _a !== void 0 ? _a : this.automaticMode;
|
|
60
64
|
this.useOwnTemperatur = (_b = data.useOwnTemperatur) !== null && _b !== void 0 ? _b : this.useOwnTemperatur;
|
|
61
|
-
this.
|
|
62
|
-
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
65
|
-
this.
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
65
|
+
this.useOwnTemperatureForRoomTemperature =
|
|
66
|
+
(_c = data.useOwnTemperatureForRoomTemperature) !== null && _c !== void 0 ? _c : this.useOwnTemperatureForRoomTemperature;
|
|
67
|
+
this.controlByPid = (_d = data.controlByPid) !== null && _d !== void 0 ? _d : this.controlByPid;
|
|
68
|
+
this.controlByTempDiff = (_e = data.controlByTempDiff) !== null && _e !== void 0 ? _e : this.controlByTempDiff;
|
|
69
|
+
this.seasonalTurnOffActive = (_f = data.seasonalTurnOffActive) !== null && _f !== void 0 ? _f : this.seasonalTurnOffActive;
|
|
70
|
+
this.seasonTurnOffDay = (_g = data.seasonTurnOffDay) !== null && _g !== void 0 ? _g : this.seasonTurnOffDay;
|
|
71
|
+
this.seasonTurnOnDay = (_h = data.seasonTurnOnDay) !== null && _h !== void 0 ? _h : this.seasonTurnOnDay;
|
|
72
|
+
this.pidForcedMinimum = (_j = data.pidForcedMinimum) !== null && _j !== void 0 ? _j : this.pidForcedMinimum;
|
|
73
|
+
this.manualDisabled = (_k = data.manualDisabled) !== null && _k !== void 0 ? _k : this.manualDisabled;
|
|
68
74
|
super.fromPartialObject(data);
|
|
69
75
|
}
|
|
70
76
|
toJSON() {
|
|
@@ -2,6 +2,7 @@ import { WindowPosition } from '../models';
|
|
|
2
2
|
import { iRoomDevice } from './iRoomDevice';
|
|
3
3
|
import { HandleSensor } from '../sharedFunctions';
|
|
4
4
|
import { Window } from '../groups';
|
|
5
|
+
import { HandleChangeAction } from '../../../models';
|
|
5
6
|
/**
|
|
6
7
|
* Interface for Handle Sensors.
|
|
7
8
|
* A handle sensor can be any device that is capable of detecting the position of a window handle e.g. a sensor, a window handle, etc.
|
|
@@ -40,4 +41,9 @@ export interface iHandleSensor extends iRoomDevice {
|
|
|
40
41
|
* @param pCallback - The callback to fire
|
|
41
42
|
*/
|
|
42
43
|
addClosedCallback(pCallback: (pValue: boolean) => void): void;
|
|
44
|
+
/**
|
|
45
|
+
* Add a callback that is called when the handle is changed to any position
|
|
46
|
+
* @param cb - The callback to fire
|
|
47
|
+
*/
|
|
48
|
+
addHandleChangeCallback(cb: (handleChangeAction: HandleChangeAction) => void): void;
|
|
43
49
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { HeaterSettings } from '../../../models';
|
|
1
|
+
import { HandleChangeAction, HeaterSettings } from '../../../models';
|
|
2
2
|
import { iRoomDevice } from './iRoomDevice';
|
|
3
3
|
import { iDisposable } from '../../services';
|
|
4
|
+
import { iTemperatureSensor } from './iTemperatureSensor';
|
|
4
5
|
/**
|
|
5
6
|
* This interface represents a heater device.
|
|
6
7
|
*
|
|
7
8
|
* For devices with {@link DeviceCapability.heater} capability.
|
|
8
9
|
*/
|
|
9
|
-
export interface iHeater extends iRoomDevice, iDisposable {
|
|
10
|
+
export interface iHeater extends iTemperatureSensor, iRoomDevice, iDisposable {
|
|
10
11
|
/**
|
|
11
12
|
* The settings of the heater
|
|
12
13
|
*/
|
|
@@ -19,14 +20,6 @@ export interface iHeater extends iRoomDevice, iDisposable {
|
|
|
19
20
|
* The current valve position of the heater (between 0 and 1.0)
|
|
20
21
|
*/
|
|
21
22
|
readonly iLevel: number;
|
|
22
|
-
/**
|
|
23
|
-
* The current temperature in degree Celsius of the heater
|
|
24
|
-
*/
|
|
25
|
-
readonly iTemperature: number;
|
|
26
|
-
/**
|
|
27
|
-
* The current room temperature in degree Celsius
|
|
28
|
-
*/
|
|
29
|
-
readonly roomTemperature: number;
|
|
30
23
|
/**
|
|
31
24
|
* The interval to persist the heater information
|
|
32
25
|
* This mainly enforces the interval to be implemented.
|
|
@@ -37,16 +30,20 @@ export interface iHeater extends iRoomDevice, iDisposable {
|
|
|
37
30
|
*/
|
|
38
31
|
seasonTurnOff: boolean;
|
|
39
32
|
/**
|
|
40
|
-
*
|
|
33
|
+
* Whether any window in the room is open.
|
|
41
34
|
*/
|
|
42
|
-
|
|
35
|
+
readonly windowOpen: boolean;
|
|
43
36
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @param newTemperatur - The new temperature in degree Celsius.
|
|
37
|
+
* Perform a check to calculate the new desired heater state
|
|
46
38
|
*/
|
|
47
|
-
|
|
39
|
+
checkAutomaticChange(): void;
|
|
48
40
|
/**
|
|
49
41
|
* Persists the current heater information to the database
|
|
50
42
|
*/
|
|
51
43
|
persistHeater(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Called when a window handle in the room changes its state
|
|
46
|
+
* @param action
|
|
47
|
+
*/
|
|
48
|
+
onHandleChange(action: HandleChangeAction): void;
|
|
52
49
|
}
|
|
@@ -4,6 +4,7 @@ export * from './iBaseDevice';
|
|
|
4
4
|
export * from './iBatteryDevice';
|
|
5
5
|
export * from './iButtonSwitch';
|
|
6
6
|
export * from './iCameraDevice';
|
|
7
|
+
export * from './iDimmableLamp';
|
|
7
8
|
export * from './iEnergyManager';
|
|
8
9
|
export * from './iExcessEnergyConsumer';
|
|
9
10
|
export * from './iGarageDoorOpener';
|
|
@@ -20,6 +20,7 @@ __exportStar(require("./iBaseDevice"), exports);
|
|
|
20
20
|
__exportStar(require("./iBatteryDevice"), exports);
|
|
21
21
|
__exportStar(require("./iButtonSwitch"), exports);
|
|
22
22
|
__exportStar(require("./iCameraDevice"), exports);
|
|
23
|
+
__exportStar(require("./iDimmableLamp"), exports);
|
|
23
24
|
__exportStar(require("./iEnergyManager"), exports);
|
|
24
25
|
__exportStar(require("./iExcessEnergyConsumer"), exports);
|
|
25
26
|
__exportStar(require("./iGarageDoorOpener"), exports);
|
|
@@ -87,7 +87,9 @@ export declare class Dachs implements iBaseDevice, iActuator {
|
|
|
87
87
|
*/
|
|
88
88
|
private onBatteryLevelChange;
|
|
89
89
|
private checkAllDesiredStates;
|
|
90
|
-
private
|
|
90
|
+
private onHeatStorageTempChange;
|
|
91
|
+
private onWarmWaterTempChange;
|
|
92
|
+
private checkWwPumpDesiredState;
|
|
91
93
|
private checkHeatingRod;
|
|
92
94
|
private shouldDachsBeStarted;
|
|
93
95
|
private checkAlternativeActuator;
|
|
@@ -63,8 +63,8 @@ class Dachs {
|
|
|
63
63
|
const energyManager = devices_1.Devices.energymanager;
|
|
64
64
|
energyManager.battery.addBatteryLevelCallback(this.onBatteryLevelChange.bind(this));
|
|
65
65
|
}
|
|
66
|
-
this.warmWaterSensor.addTempChangeCallback(this.
|
|
67
|
-
this.heatStorageTempSensor.addTempChangeCallback(this.
|
|
66
|
+
this.warmWaterSensor.addTempChangeCallback(this.onWarmWaterTempChange.bind(this));
|
|
67
|
+
this.heatStorageTempSensor.addTempChangeCallback(this.onHeatStorageTempChange.bind(this));
|
|
68
68
|
}
|
|
69
69
|
/** @inheritDoc */
|
|
70
70
|
get info() {
|
|
@@ -220,6 +220,7 @@ class Dachs {
|
|
|
220
220
|
const shouldDachsBeStarted = this.shouldDachsBeStarted(action, batteryLevel);
|
|
221
221
|
this.checkHeatingRod(action, batteryLevel);
|
|
222
222
|
this.checkAlternativeActuator(shouldDachsBeStarted, action);
|
|
223
|
+
this.checkWwPumpDesiredState(action);
|
|
223
224
|
if (!shouldDachsBeStarted) {
|
|
224
225
|
return;
|
|
225
226
|
}
|
|
@@ -227,7 +228,15 @@ class Dachs {
|
|
|
227
228
|
setStateCommand.overrideCommandSource = models_1.CommandSource.Force;
|
|
228
229
|
this.setActuator(setStateCommand);
|
|
229
230
|
}
|
|
230
|
-
|
|
231
|
+
onHeatStorageTempChange(action) {
|
|
232
|
+
var _a, _b;
|
|
233
|
+
this.checkAllDesiredStates(action, (_b = (_a = devices_1.Devices.energymanager) === null || _a === void 0 ? void 0 : _a.batteryLevel) !== null && _b !== void 0 ? _b : 0);
|
|
234
|
+
}
|
|
235
|
+
onWarmWaterTempChange(action) {
|
|
236
|
+
var _a, _b;
|
|
237
|
+
this.checkAllDesiredStates(action, (_b = (_a = devices_1.Devices.energymanager) === null || _a === void 0 ? void 0 : _a.batteryLevel) !== null && _b !== void 0 ? _b : 0);
|
|
238
|
+
}
|
|
239
|
+
checkWwPumpDesiredState(action) {
|
|
231
240
|
var _a, _b;
|
|
232
241
|
if (this.warmWaterPump === undefined) {
|
|
233
242
|
// We have no control over the warm water pump --> nothing to do
|
|
@@ -288,7 +297,7 @@ class Dachs {
|
|
|
288
297
|
this.heatingRod.setActuator(setAction);
|
|
289
298
|
}
|
|
290
299
|
shouldDachsBeStarted(action, batteryLevel) {
|
|
291
|
-
var _a;
|
|
300
|
+
var _a, _b;
|
|
292
301
|
if (this.blockDachsStart !== undefined) {
|
|
293
302
|
if (batteryLevel > this.settings.batteryLevelPreventStartThreshold) {
|
|
294
303
|
const blockAction = new models_1.ActuatorSetStateCommand(action, true, `Battery reached ${batteryLevel}%, Dachs should not run any more`, null);
|
|
@@ -301,7 +310,7 @@ class Dachs {
|
|
|
301
310
|
this.blockDachsStart.setActuator(liftAction);
|
|
302
311
|
}
|
|
303
312
|
else if (((_a = services_1.SettingsService.settings.heaterSettings) === null || _a === void 0 ? void 0 : _a.mode) === config_1.HeatingMode.Winter &&
|
|
304
|
-
this.heatStorageTempSensor.temperatureSensor.temperature <
|
|
313
|
+
this.heatStorageTempSensor.temperatureSensor.temperature < this.settings.winterMinimumPreNightHeatStorageTemp &&
|
|
305
314
|
services_1.Utils.dateByTimeSpan(21, 30) < new Date()) {
|
|
306
315
|
const liftWinterAction = new models_1.ActuatorSetStateCommand(action, false, `Battery at ${batteryLevel}% but it is winter, we are nearing night and heat storage is kinda cold: Dachs is now allowed to run if needed`, null);
|
|
307
316
|
this.blockDachsStart.setActuator(liftWinterAction);
|
|
@@ -315,6 +324,11 @@ class Dachs {
|
|
|
315
324
|
// We are already running
|
|
316
325
|
return false;
|
|
317
326
|
}
|
|
327
|
+
if (((_b = services_1.SettingsService.settings.heaterSettings) === null || _b === void 0 ? void 0 : _b.mode) === config_1.HeatingMode.Winter &&
|
|
328
|
+
this.heatStorageTempSensor.temperatureSensor.temperature < this.settings.winterMinimumHeatStorageTemp) {
|
|
329
|
+
// It is winter and heat storage is kinda cold --> Start
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
318
332
|
const dayType = services_1.TimeCallbackService.dayType(new services_1.SunTimeOffsets());
|
|
319
333
|
if ((dayType === models_1.TimeOfDay.Daylight || dayType === models_1.TimeOfDay.BeforeSunrise) &&
|
|
320
334
|
batteryLevel > this.settings.batteryLevelTurnOnThreshold) {
|
|
@@ -33,6 +33,8 @@ const _ = __importStar(require("lodash"));
|
|
|
33
33
|
const keyTemplates_1 = __importDefault(require("./keyTemplates"));
|
|
34
34
|
const services_1 = require("../../../services");
|
|
35
35
|
const models_1 = require("../../../../models");
|
|
36
|
+
const http = __importStar(require("node:http"));
|
|
37
|
+
const https = __importStar(require("node:https"));
|
|
36
38
|
/**
|
|
37
39
|
* axios HTTP Client Class
|
|
38
40
|
* - with some prepared fetch functions for data
|
|
@@ -47,6 +49,8 @@ class DachsHttpClient {
|
|
|
47
49
|
this.options = options;
|
|
48
50
|
//combine parameter to baseUrl
|
|
49
51
|
//check http prefix
|
|
52
|
+
axios_1.default.defaults.httpsAgent = new https.Agent({ keepAlive: false });
|
|
53
|
+
axios_1.default.defaults.httpAgent = new http.Agent({ keepAlive: false });
|
|
50
54
|
const protocol = options.protocol ? options.protocol : 'http';
|
|
51
55
|
this.options.host = this.options.host.startsWith('http') ? this.options.host : `${protocol}://${this.options.host}`;
|
|
52
56
|
//combine all parameter for url
|
|
@@ -65,6 +65,11 @@ class DeviceCluster {
|
|
|
65
65
|
case deviceType_1.DeviceType.HmIpGriff:
|
|
66
66
|
clusterTypes.push(device_cluster_type_1.DeviceClusterType.Handle);
|
|
67
67
|
break;
|
|
68
|
+
case deviceType_1.DeviceType.ZigbeeSodaHandle:
|
|
69
|
+
clusterTypes.push(device_cluster_type_1.DeviceClusterType.Handle);
|
|
70
|
+
clusterTypes.push(device_cluster_type_1.DeviceClusterType.TemperaturSensor);
|
|
71
|
+
clusterTypes.push(device_cluster_type_1.DeviceClusterType.HumiditySensor);
|
|
72
|
+
break;
|
|
68
73
|
case deviceType_1.DeviceType.HmIpHeizgruppe:
|
|
69
74
|
clusterTypes.push(device_cluster_type_1.DeviceClusterType.Heater);
|
|
70
75
|
clusterTypes.push(device_cluster_type_1.DeviceClusterType.TemperaturSensor);
|
|
@@ -78,6 +83,7 @@ class DeviceCluster {
|
|
|
78
83
|
case deviceType_1.DeviceType.HmIpBewegung:
|
|
79
84
|
case deviceType_1.DeviceType.ZigbeeAquaraMotion:
|
|
80
85
|
case deviceType_1.DeviceType.ZigbeeSonoffMotion:
|
|
86
|
+
case deviceType_1.DeviceType.ZigbeeTuyaMotion:
|
|
81
87
|
case deviceType_1.DeviceType.HmIpPraezenz:
|
|
82
88
|
clusterTypes.push(device_cluster_type_1.DeviceClusterType.MotionDetection);
|
|
83
89
|
break;
|
|
@@ -43,6 +43,7 @@ var DeviceType;
|
|
|
43
43
|
DeviceType[DeviceType["ZigbeeUbisysLampe"] = 225] = "ZigbeeUbisysLampe";
|
|
44
44
|
DeviceType[DeviceType["ZigbeeInnr142C"] = 226] = "ZigbeeInnr142C";
|
|
45
45
|
DeviceType[DeviceType["ZigbeeSodaHandle"] = 227] = "ZigbeeSodaHandle";
|
|
46
|
+
DeviceType[DeviceType["ZigbeeTuyaMotion"] = 228] = "ZigbeeTuyaMotion";
|
|
46
47
|
DeviceType[DeviceType["JsEnergyManager"] = 301] = "JsEnergyManager";
|
|
47
48
|
DeviceType[DeviceType["RoomScene"] = 401] = "RoomScene";
|
|
48
49
|
DeviceType[DeviceType["ShellyTrv"] = 402] = "ShellyTrv";
|
|
@@ -223,6 +223,9 @@ class Devices {
|
|
|
223
223
|
case 'TuyaValve':
|
|
224
224
|
d = new zigbee_1.ZigbeeTuyaValve(zigbeeInfo);
|
|
225
225
|
break;
|
|
226
|
+
case 'TuyaMotion':
|
|
227
|
+
d = new zigbee_1.ZigbeeTuyaMotion(zigbeeInfo);
|
|
228
|
+
break;
|
|
226
229
|
case 'EuroHeater':
|
|
227
230
|
d = new zigbee_1.ZigbeeEuroHeater(zigbeeInfo);
|
|
228
231
|
break;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WindowPosition } from '../models';
|
|
2
|
-
import { ShutterPositionChangedAction, WindowRestoreDesiredPositionCommand, WindowSetDesiredPositionCommand } from '../../../models';
|
|
2
|
+
import { HandleChangeAction, ShutterPositionChangedAction, WindowRestoreDesiredPositionCommand, WindowSetDesiredPositionCommand } from '../../../models';
|
|
3
3
|
import { iHandleSensor, iShutter, iVibrationSensor } from '../baseDeviceInterfaces';
|
|
4
4
|
import { BaseGroup } from './base-group';
|
|
5
5
|
import { ZigbeeMagnetContact } from '../zigbee';
|
|
@@ -19,6 +19,11 @@ export declare class Window extends BaseGroup {
|
|
|
19
19
|
* @returns {boolean} true if any shutter is down
|
|
20
20
|
*/
|
|
21
21
|
get anyShutterDown(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Checks if any handle is not closed
|
|
24
|
+
* @returns {boolean} true if any handle is not closed
|
|
25
|
+
*/
|
|
26
|
+
get anyHandleNotClosed(): boolean;
|
|
22
27
|
constructor(roomName: string, handleIds?: string[], vibrationIds?: string[], shutterIds?: string[], magnetIds?: string[]);
|
|
23
28
|
/**
|
|
24
29
|
* sets the desired Pos and moves rollo to this level
|
|
@@ -33,4 +38,5 @@ export declare class Window extends BaseGroup {
|
|
|
33
38
|
initialize(): void;
|
|
34
39
|
rolloPositionChange(action: ShutterPositionChangedAction): void;
|
|
35
40
|
restoreDesiredPosition(c: WindowRestoreDesiredPositionCommand): void;
|
|
41
|
+
addHandleChangeCallback(cb: (handleChangeAction: HandleChangeAction) => void): void;
|
|
36
42
|
}
|
|
@@ -25,6 +25,15 @@ class Window extends base_group_1.BaseGroup {
|
|
|
25
25
|
return s.currentLevel === 0;
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Checks if any handle is not closed
|
|
30
|
+
* @returns {boolean} true if any handle is not closed
|
|
31
|
+
*/
|
|
32
|
+
get anyHandleNotClosed() {
|
|
33
|
+
return this.getHandle().some((h) => {
|
|
34
|
+
return h.position !== models_1.WindowPosition.closed;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
28
37
|
constructor(roomName, handleIds = [], vibrationIds = [], shutterIds = [], magnetIds = []) {
|
|
29
38
|
super(roomName, group_type_1.GroupType.Window);
|
|
30
39
|
this.handleIds = handleIds;
|
|
@@ -46,7 +55,7 @@ class Window extends base_group_1.BaseGroup {
|
|
|
46
55
|
this.restoreDesiredPosition(new models_2.WindowRestoreDesiredPositionCommand(c));
|
|
47
56
|
}
|
|
48
57
|
getHandle() {
|
|
49
|
-
return this.deviceCluster.
|
|
58
|
+
return this.deviceCluster.getDevicesByType(device_cluster_type_1.DeviceClusterType.Handle);
|
|
50
59
|
}
|
|
51
60
|
getMagnetContact() {
|
|
52
61
|
return this.deviceCluster.getIoBrokerDevicesByType(device_cluster_type_1.DeviceClusterType.MagnetContact);
|
|
@@ -122,5 +131,10 @@ class Window extends base_group_1.BaseGroup {
|
|
|
122
131
|
restoreDesiredPosition(c) {
|
|
123
132
|
services_1.ShutterService.windowAllToPosition(this, new models_2.ShutterSetLevelCommand(c, this._desiredPosition));
|
|
124
133
|
}
|
|
134
|
+
addHandleChangeCallback(cb) {
|
|
135
|
+
this.getHandle().forEach((griff) => {
|
|
136
|
+
griff.addHandleChangeCallback(cb);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
125
139
|
}
|
|
126
140
|
exports.Window = Window;
|
|
@@ -47,8 +47,13 @@ class HeatGroup extends base_group_1.BaseGroup {
|
|
|
47
47
|
get temperature() {
|
|
48
48
|
let temp = baseDeviceInterfaces_1.UNDEFINED_TEMP_VALUE;
|
|
49
49
|
let count = 0;
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const usedIds = [];
|
|
51
|
+
this.getHeater().forEach((heaterAsSensor) => {
|
|
52
|
+
usedIds.push(heaterAsSensor.id);
|
|
53
|
+
if (!heaterAsSensor.settings.useOwnTemperatureForRoomTemperature) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const sensorValue = heaterAsSensor.iTemperature;
|
|
52
57
|
if (sensorValue === baseDeviceInterfaces_1.UNDEFINED_TEMP_VALUE) {
|
|
53
58
|
return;
|
|
54
59
|
}
|
|
@@ -59,11 +64,12 @@ class HeatGroup extends base_group_1.BaseGroup {
|
|
|
59
64
|
}
|
|
60
65
|
temp = (temp * count + sensorValue) / ++count;
|
|
61
66
|
});
|
|
62
|
-
this.
|
|
63
|
-
if (
|
|
67
|
+
this.getTempSensors().forEach((sensor) => {
|
|
68
|
+
if (usedIds.includes(sensor.id)) {
|
|
69
|
+
// Heater which correctly implement sensor as well.
|
|
64
70
|
return;
|
|
65
71
|
}
|
|
66
|
-
const sensorValue =
|
|
72
|
+
const sensorValue = sensor.iTemperature;
|
|
67
73
|
if (sensorValue === baseDeviceInterfaces_1.UNDEFINED_TEMP_VALUE) {
|
|
68
74
|
return;
|
|
69
75
|
}
|
|
@@ -114,6 +120,7 @@ class HeatGroup extends base_group_1.BaseGroup {
|
|
|
114
120
|
return this.deviceCluster.getDevicesByType(device_cluster_type_1.DeviceClusterType.Ac);
|
|
115
121
|
}
|
|
116
122
|
initialize() {
|
|
123
|
+
var _a;
|
|
117
124
|
services_1.Utils.guardedTimeout(() => {
|
|
118
125
|
this.settings.initializeFromDb(this);
|
|
119
126
|
}, 200, this);
|
|
@@ -125,6 +132,11 @@ class HeatGroup extends base_group_1.BaseGroup {
|
|
|
125
132
|
this.getOwnAcDevices().forEach((acDev) => {
|
|
126
133
|
acDev.room = this.getRoom();
|
|
127
134
|
});
|
|
135
|
+
(_a = this.getRoom().WindowGroup) === null || _a === void 0 ? void 0 : _a.addHandleChangeCallback((handleChangeAction) => {
|
|
136
|
+
this.getHeater().forEach((heater) => {
|
|
137
|
+
heater.onHandleChange(handleChangeAction);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
128
140
|
}
|
|
129
141
|
/**
|
|
130
142
|
* Sets all ACs to new desired Value
|
|
@@ -155,10 +167,15 @@ class HeatGroup extends base_group_1.BaseGroup {
|
|
|
155
167
|
if (temp == baseDeviceInterfaces_1.UNDEFINED_TEMP_VALUE) {
|
|
156
168
|
return;
|
|
157
169
|
}
|
|
170
|
+
const usedIds = [];
|
|
158
171
|
this.getHeater().forEach((heater) => {
|
|
172
|
+
usedIds.push(heater.id);
|
|
159
173
|
heater.onTemperaturChange(temp);
|
|
160
174
|
});
|
|
161
175
|
this.getTempSensors().forEach((sensor) => {
|
|
176
|
+
if (usedIds.includes(sensor.id)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
162
179
|
sensor.onTemperaturChange(temp);
|
|
163
180
|
});
|
|
164
181
|
this.getOwnAcDevices().forEach((ac) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RoomRestoreShutterPositionCommand, ShutterSunriseUpCommand, TimeCallback, WindowSetDesiredPositionCommand, WindowSetRolloByWeatherStatusCommand } from '../../../models';
|
|
1
|
+
import { HandleChangeAction, RoomRestoreShutterPositionCommand, ShutterSunriseUpCommand, TimeCallback, WindowSetDesiredPositionCommand, WindowSetRolloByWeatherStatusCommand } from '../../../models';
|
|
2
2
|
import { Window } from './Window';
|
|
3
3
|
import { BaseGroup } from './base-group';
|
|
4
4
|
export declare class WindowGroup extends BaseGroup {
|
|
@@ -20,7 +20,17 @@ export declare class WindowGroup extends BaseGroup {
|
|
|
20
20
|
* @returns {boolean} True if there is atleast one shutte with level of 0%.
|
|
21
21
|
*/
|
|
22
22
|
get anyShutterDown(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Checks if any handle of any window is open
|
|
25
|
+
* @returns {boolean} True if there is atleast one handle that is open.
|
|
26
|
+
*/
|
|
27
|
+
get anyWindowOpen(): boolean;
|
|
23
28
|
constructor(roomName: string, windows: Window[]);
|
|
29
|
+
/**
|
|
30
|
+
* Adds Callbacks to each window and their handles.
|
|
31
|
+
* @param cb - The callback to execute on met condition.
|
|
32
|
+
*/
|
|
33
|
+
addHandleChangeCallback(cb: (handleChangeAction: HandleChangeAction) => void): void;
|
|
24
34
|
setDesiredPosition(c: WindowSetDesiredPositionCommand): void;
|
|
25
35
|
initialize(): void;
|
|
26
36
|
recalcTimeCallbacks(): void;
|