@ecobridge.xyz/devicemanager 3.0.2

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.
Files changed (137) hide show
  1. package/.gitea/workflows/default_nottags.yaml +66 -0
  2. package/.gitea/workflows/default_tags.yaml +124 -0
  3. package/.vscode/launch.json +11 -0
  4. package/.vscode/settings.json +26 -0
  5. package/changelog.md +91 -0
  6. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  7. package/dist_ts/00_commitinfo_data.js +9 -0
  8. package/dist_ts/device/device.classes.device.d.ts +205 -0
  9. package/dist_ts/device/device.classes.device.js +344 -0
  10. package/dist_ts/devicemanager.classes.devicemanager.d.ts +210 -0
  11. package/dist_ts/devicemanager.classes.devicemanager.js +835 -0
  12. package/dist_ts/discovery/discovery.classes.homeassistant.d.ts +101 -0
  13. package/dist_ts/discovery/discovery.classes.homeassistant.js +313 -0
  14. package/dist_ts/discovery/discovery.classes.mdns.d.ts +90 -0
  15. package/dist_ts/discovery/discovery.classes.mdns.js +291 -0
  16. package/dist_ts/discovery/discovery.classes.networkscanner.d.ts +64 -0
  17. package/dist_ts/discovery/discovery.classes.networkscanner.js +535 -0
  18. package/dist_ts/discovery/discovery.classes.ssdp.d.ts +112 -0
  19. package/dist_ts/discovery/discovery.classes.ssdp.js +255 -0
  20. package/dist_ts/factories/index.d.ts +190 -0
  21. package/dist_ts/factories/index.js +350 -0
  22. package/dist_ts/features/feature.abstract.d.ts +118 -0
  23. package/dist_ts/features/feature.abstract.js +172 -0
  24. package/dist_ts/features/feature.camera.d.ts +95 -0
  25. package/dist_ts/features/feature.camera.js +162 -0
  26. package/dist_ts/features/feature.climate.d.ts +174 -0
  27. package/dist_ts/features/feature.climate.js +328 -0
  28. package/dist_ts/features/feature.cover.d.ts +121 -0
  29. package/dist_ts/features/feature.cover.js +217 -0
  30. package/dist_ts/features/feature.fan.d.ts +127 -0
  31. package/dist_ts/features/feature.fan.js +235 -0
  32. package/dist_ts/features/feature.light.d.ts +156 -0
  33. package/dist_ts/features/feature.light.js +296 -0
  34. package/dist_ts/features/feature.lock.d.ts +103 -0
  35. package/dist_ts/features/feature.lock.js +170 -0
  36. package/dist_ts/features/feature.playback.d.ts +98 -0
  37. package/dist_ts/features/feature.playback.js +191 -0
  38. package/dist_ts/features/feature.power.d.ts +79 -0
  39. package/dist_ts/features/feature.power.js +173 -0
  40. package/dist_ts/features/feature.print.d.ts +78 -0
  41. package/dist_ts/features/feature.print.js +226 -0
  42. package/dist_ts/features/feature.scan.d.ts +79 -0
  43. package/dist_ts/features/feature.scan.js +315 -0
  44. package/dist_ts/features/feature.sensor.d.ts +95 -0
  45. package/dist_ts/features/feature.sensor.js +147 -0
  46. package/dist_ts/features/feature.snmp.d.ts +88 -0
  47. package/dist_ts/features/feature.snmp.js +175 -0
  48. package/dist_ts/features/feature.switch.d.ts +75 -0
  49. package/dist_ts/features/feature.switch.js +126 -0
  50. package/dist_ts/features/feature.volume.d.ts +104 -0
  51. package/dist_ts/features/feature.volume.js +186 -0
  52. package/dist_ts/features/index.d.ts +19 -0
  53. package/dist_ts/features/index.js +23 -0
  54. package/dist_ts/helpers/helpers.iprange.d.ts +35 -0
  55. package/dist_ts/helpers/helpers.iprange.js +151 -0
  56. package/dist_ts/helpers/helpers.retry.d.ts +25 -0
  57. package/dist_ts/helpers/helpers.retry.js +69 -0
  58. package/dist_ts/index.d.ts +15 -0
  59. package/dist_ts/index.js +40 -0
  60. package/dist_ts/interfaces/feature.interfaces.d.ts +255 -0
  61. package/dist_ts/interfaces/feature.interfaces.js +6 -0
  62. package/dist_ts/interfaces/homeassistant.interfaces.d.ts +550 -0
  63. package/dist_ts/interfaces/homeassistant.interfaces.js +111 -0
  64. package/dist_ts/interfaces/index.d.ts +330 -0
  65. package/dist_ts/interfaces/index.js +16 -0
  66. package/dist_ts/interfaces/smarthome.interfaces.d.ts +282 -0
  67. package/dist_ts/interfaces/smarthome.interfaces.js +7 -0
  68. package/dist_ts/paths.d.ts +1 -0
  69. package/dist_ts/paths.js +3 -0
  70. package/dist_ts/plugins.d.ts +23 -0
  71. package/dist_ts/plugins.js +30 -0
  72. package/dist_ts/protocols/index.d.ts +12 -0
  73. package/dist_ts/protocols/index.js +21 -0
  74. package/dist_ts/protocols/protocol.escl.d.ts +58 -0
  75. package/dist_ts/protocols/protocol.escl.js +364 -0
  76. package/dist_ts/protocols/protocol.homeassistant.d.ts +248 -0
  77. package/dist_ts/protocols/protocol.homeassistant.js +611 -0
  78. package/dist_ts/protocols/protocol.ipp.d.ts +45 -0
  79. package/dist_ts/protocols/protocol.ipp.js +284 -0
  80. package/dist_ts/protocols/protocol.nut.d.ts +160 -0
  81. package/dist_ts/protocols/protocol.nut.js +364 -0
  82. package/dist_ts/protocols/protocol.sane.d.ts +104 -0
  83. package/dist_ts/protocols/protocol.sane.js +597 -0
  84. package/dist_ts/protocols/protocol.snmp.d.ts +133 -0
  85. package/dist_ts/protocols/protocol.snmp.js +333 -0
  86. package/dist_ts/protocols/protocol.upnp.d.ts +207 -0
  87. package/dist_ts/protocols/protocol.upnp.js +442 -0
  88. package/dist_ts/protocols/protocol.upssnmp.d.ts +160 -0
  89. package/dist_ts/protocols/protocol.upssnmp.js +263 -0
  90. package/npmextra.json +24 -0
  91. package/package.json +39 -0
  92. package/readme.hints.md +115 -0
  93. package/readme.md +624 -0
  94. package/test/test.ts +261 -0
  95. package/ts/00_commitinfo_data.ts +8 -0
  96. package/ts/device/device.classes.device.ts +454 -0
  97. package/ts/devicemanager.classes.devicemanager.ts +1219 -0
  98. package/ts/discovery/discovery.classes.homeassistant.ts +376 -0
  99. package/ts/discovery/discovery.classes.mdns.ts +347 -0
  100. package/ts/discovery/discovery.classes.networkscanner.ts +648 -0
  101. package/ts/discovery/discovery.classes.ssdp.ts +357 -0
  102. package/ts/factories/index.ts +696 -0
  103. package/ts/features/feature.abstract.ts +251 -0
  104. package/ts/features/feature.camera.ts +214 -0
  105. package/ts/features/feature.climate.ts +407 -0
  106. package/ts/features/feature.cover.ts +278 -0
  107. package/ts/features/feature.fan.ts +296 -0
  108. package/ts/features/feature.light.ts +369 -0
  109. package/ts/features/feature.lock.ts +223 -0
  110. package/ts/features/feature.playback.ts +246 -0
  111. package/ts/features/feature.power.ts +231 -0
  112. package/ts/features/feature.print.ts +297 -0
  113. package/ts/features/feature.scan.ts +370 -0
  114. package/ts/features/feature.sensor.ts +202 -0
  115. package/ts/features/feature.snmp.ts +235 -0
  116. package/ts/features/feature.switch.ts +170 -0
  117. package/ts/features/feature.volume.ts +256 -0
  118. package/ts/features/index.ts +25 -0
  119. package/ts/helpers/helpers.iprange.ts +172 -0
  120. package/ts/helpers/helpers.retry.ts +100 -0
  121. package/ts/index.ts +165 -0
  122. package/ts/interfaces/feature.interfaces.ts +359 -0
  123. package/ts/interfaces/homeassistant.interfaces.ts +666 -0
  124. package/ts/interfaces/index.ts +421 -0
  125. package/ts/interfaces/smarthome.interfaces.ts +421 -0
  126. package/ts/paths.ts +5 -0
  127. package/ts/plugins.ts +41 -0
  128. package/ts/protocols/index.ts +59 -0
  129. package/ts/protocols/protocol.escl.ts +439 -0
  130. package/ts/protocols/protocol.homeassistant.ts +737 -0
  131. package/ts/protocols/protocol.ipp.ts +329 -0
  132. package/ts/protocols/protocol.nut.ts +471 -0
  133. package/ts/protocols/protocol.sane.ts +694 -0
  134. package/ts/protocols/protocol.snmp.ts +439 -0
  135. package/ts/protocols/protocol.upnp.ts +627 -0
  136. package/ts/protocols/protocol.upssnmp.ts +377 -0
  137. package/tsconfig.json +12 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Sensor Feature
3
+ * Provides read-only state for sensors (temperature, humidity, power, etc.)
4
+ */
5
+ import { Feature, type TDeviceReference } from './feature.abstract.js';
6
+ import type { IFeatureOptions } from '../interfaces/feature.interfaces.js';
7
+ import type { TSensorProtocol, TSensorDeviceClass, TSensorStateClass, ISensorCapabilities, ISensorState, ISensorFeatureInfo, ISensorProtocolClient } from '../interfaces/smarthome.interfaces.js';
8
+ /**
9
+ * Options for creating a SensorFeature
10
+ */
11
+ export interface ISensorFeatureOptions extends IFeatureOptions {
12
+ /** Protocol type */
13
+ protocol: TSensorProtocol;
14
+ /** Entity ID (for Home Assistant) */
15
+ entityId: string;
16
+ /** Protocol client for reading sensor state */
17
+ protocolClient: ISensorProtocolClient;
18
+ /** Device class (temperature, humidity, etc.) */
19
+ deviceClass?: TSensorDeviceClass;
20
+ /** State class (measurement, total, etc.) */
21
+ stateClass?: TSensorStateClass;
22
+ /** Unit of measurement */
23
+ unit?: string;
24
+ /** Precision (decimal places) */
25
+ precision?: number;
26
+ }
27
+ /**
28
+ * Sensor Feature - read-only state values
29
+ *
30
+ * Protocol-agnostic: works with Home Assistant, MQTT, SNMP, etc.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const sensor = device.getFeature<SensorFeature>('sensor');
35
+ * if (sensor) {
36
+ * await sensor.refreshState();
37
+ * console.log(`Temperature: ${sensor.value} ${sensor.unit}`);
38
+ * }
39
+ * ```
40
+ */
41
+ export declare class SensorFeature extends Feature {
42
+ readonly type: "sensor";
43
+ readonly protocol: TSensorProtocol;
44
+ /** Entity ID (e.g., "sensor.living_room_temperature") */
45
+ readonly entityId: string;
46
+ /** Capabilities */
47
+ readonly capabilities: ISensorCapabilities;
48
+ /** Current state */
49
+ protected _value: string | number | boolean;
50
+ protected _numericValue?: number;
51
+ protected _unit?: string;
52
+ protected _lastUpdated: Date;
53
+ /** Protocol client for reading sensor state */
54
+ private protocolClient;
55
+ constructor(device: TDeviceReference, port: number, options: ISensorFeatureOptions);
56
+ /**
57
+ * Get current value (cached)
58
+ */
59
+ get value(): string | number | boolean;
60
+ /**
61
+ * Get numeric value if available (cached)
62
+ */
63
+ get numericValue(): number | undefined;
64
+ /**
65
+ * Get unit of measurement
66
+ */
67
+ get unit(): string | undefined;
68
+ /**
69
+ * Get device class
70
+ */
71
+ get deviceClass(): TSensorDeviceClass | undefined;
72
+ /**
73
+ * Get state class
74
+ */
75
+ get stateClass(): TSensorStateClass | undefined;
76
+ /**
77
+ * Get last updated timestamp
78
+ */
79
+ get lastUpdated(): Date;
80
+ protected doConnect(): Promise<void>;
81
+ protected doDisconnect(): Promise<void>;
82
+ /**
83
+ * Refresh state from the device
84
+ */
85
+ refreshState(): Promise<ISensorState>;
86
+ /**
87
+ * Update state from external source (e.g., state change event)
88
+ */
89
+ updateState(state: ISensorState): void;
90
+ /**
91
+ * Internal state update
92
+ */
93
+ private updateStateInternal;
94
+ getFeatureInfo(): ISensorFeatureInfo;
95
+ }
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Sensor Feature
3
+ * Provides read-only state for sensors (temperature, humidity, power, etc.)
4
+ */
5
+ import { Feature } from './feature.abstract.js';
6
+ /**
7
+ * Sensor Feature - read-only state values
8
+ *
9
+ * Protocol-agnostic: works with Home Assistant, MQTT, SNMP, etc.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const sensor = device.getFeature<SensorFeature>('sensor');
14
+ * if (sensor) {
15
+ * await sensor.refreshState();
16
+ * console.log(`Temperature: ${sensor.value} ${sensor.unit}`);
17
+ * }
18
+ * ```
19
+ */
20
+ export class SensorFeature extends Feature {
21
+ type = 'sensor';
22
+ protocol;
23
+ /** Entity ID (e.g., "sensor.living_room_temperature") */
24
+ entityId;
25
+ /** Capabilities */
26
+ capabilities;
27
+ /** Current state */
28
+ _value = '';
29
+ _numericValue;
30
+ _unit;
31
+ _lastUpdated = new Date();
32
+ /** Protocol client for reading sensor state */
33
+ protocolClient;
34
+ constructor(device, port, options) {
35
+ super(device, port, options);
36
+ this.protocol = options.protocol;
37
+ this.entityId = options.entityId;
38
+ this.protocolClient = options.protocolClient;
39
+ this.capabilities = {
40
+ deviceClass: options.deviceClass,
41
+ stateClass: options.stateClass,
42
+ unit: options.unit,
43
+ precision: options.precision,
44
+ };
45
+ this._unit = options.unit;
46
+ }
47
+ // ============================================================================
48
+ // Properties
49
+ // ============================================================================
50
+ /**
51
+ * Get current value (cached)
52
+ */
53
+ get value() {
54
+ return this._value;
55
+ }
56
+ /**
57
+ * Get numeric value if available (cached)
58
+ */
59
+ get numericValue() {
60
+ return this._numericValue;
61
+ }
62
+ /**
63
+ * Get unit of measurement
64
+ */
65
+ get unit() {
66
+ return this._unit;
67
+ }
68
+ /**
69
+ * Get device class
70
+ */
71
+ get deviceClass() {
72
+ return this.capabilities.deviceClass;
73
+ }
74
+ /**
75
+ * Get state class
76
+ */
77
+ get stateClass() {
78
+ return this.capabilities.stateClass;
79
+ }
80
+ /**
81
+ * Get last updated timestamp
82
+ */
83
+ get lastUpdated() {
84
+ return this._lastUpdated;
85
+ }
86
+ // ============================================================================
87
+ // Connection
88
+ // ============================================================================
89
+ async doConnect() {
90
+ // Fetch initial state
91
+ try {
92
+ const state = await this.protocolClient.getState(this.entityId);
93
+ this.updateStateInternal(state);
94
+ }
95
+ catch {
96
+ // Ignore errors fetching initial state
97
+ }
98
+ }
99
+ async doDisconnect() {
100
+ // Nothing to disconnect
101
+ }
102
+ // ============================================================================
103
+ // Sensor Reading
104
+ // ============================================================================
105
+ /**
106
+ * Refresh state from the device
107
+ */
108
+ async refreshState() {
109
+ const state = await this.protocolClient.getState(this.entityId);
110
+ this.updateStateInternal(state);
111
+ return state;
112
+ }
113
+ /**
114
+ * Update state from external source (e.g., state change event)
115
+ */
116
+ updateState(state) {
117
+ this.updateStateInternal(state);
118
+ this.emit('state:changed', state);
119
+ }
120
+ /**
121
+ * Internal state update
122
+ */
123
+ updateStateInternal(state) {
124
+ this._value = state.value;
125
+ this._numericValue = state.numericValue;
126
+ this._unit = state.unit || this._unit;
127
+ this._lastUpdated = state.lastUpdated;
128
+ }
129
+ // ============================================================================
130
+ // Feature Info
131
+ // ============================================================================
132
+ getFeatureInfo() {
133
+ return {
134
+ ...this.getBaseFeatureInfo(),
135
+ type: 'sensor',
136
+ protocol: this.protocol,
137
+ capabilities: this.capabilities,
138
+ currentState: {
139
+ value: this._value,
140
+ numericValue: this._numericValue,
141
+ unit: this._unit,
142
+ lastUpdated: this._lastUpdated,
143
+ },
144
+ };
145
+ }
146
+ }
147
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS5zZW5zb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9mZWF0dXJlcy9mZWF0dXJlLnNlbnNvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUF5QixNQUFNLHVCQUF1QixDQUFDO0FBZ0N2RTs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxPQUFPLGFBQWMsU0FBUSxPQUFPO0lBQ3hCLElBQUksR0FBRyxRQUFpQixDQUFDO0lBQ3pCLFFBQVEsQ0FBa0I7SUFFMUMseURBQXlEO0lBQ3pDLFFBQVEsQ0FBUztJQUVqQyxtQkFBbUI7SUFDSCxZQUFZLENBQXNCO0lBRWxELG9CQUFvQjtJQUNWLE1BQU0sR0FBOEIsRUFBRSxDQUFDO0lBQ3ZDLGFBQWEsQ0FBVTtJQUN2QixLQUFLLENBQVU7SUFDZixZQUFZLEdBQVMsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUUxQywrQ0FBK0M7SUFDdkMsY0FBYyxDQUF3QjtJQUU5QyxZQUNFLE1BQXdCLEVBQ3hCLElBQVksRUFDWixPQUE4QjtRQUU5QixLQUFLLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztRQUM3QyxJQUFJLENBQUMsWUFBWSxHQUFHO1lBQ2xCLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVztZQUNoQyxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7WUFDOUIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQ2xCLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUztTQUM3QixDQUFDO1FBQ0YsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMs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
@@ -0,0 +1,88 @@
1
+ /**
2
+ * SNMP Feature
3
+ * Provides SNMP query capability for network management
4
+ */
5
+ import { Feature, type TDeviceReference } from './feature.abstract.js';
6
+ import type { TSnmpVersion, ISnmpVarbind, ISnmpFeatureInfo, IFeatureOptions } from '../interfaces/feature.interfaces.js';
7
+ /**
8
+ * Options for creating an SnmpFeature
9
+ */
10
+ export interface ISnmpFeatureOptions extends IFeatureOptions {
11
+ version?: TSnmpVersion;
12
+ community?: string;
13
+ username?: string;
14
+ authProtocol?: 'md5' | 'sha';
15
+ authKey?: string;
16
+ privProtocol?: 'des' | 'aes';
17
+ privKey?: string;
18
+ }
19
+ /**
20
+ * SNMP Feature - provides SNMP query capability
21
+ *
22
+ * Allows querying devices via SNMP for monitoring and management.
23
+ * Many network devices (printers, switches, UPS) support SNMP.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const snmp = device.getFeature<SnmpFeature>('snmp');
28
+ * if (snmp) {
29
+ * const sysDescr = await snmp.get('1.3.6.1.2.1.1.1.0');
30
+ * console.log(`System: ${sysDescr.value}`);
31
+ *
32
+ * const interfaces = await snmp.walk('1.3.6.1.2.1.2.2.1');
33
+ * console.log(`Found ${interfaces.length} interface entries`);
34
+ * }
35
+ * ```
36
+ */
37
+ export declare class SnmpFeature extends Feature {
38
+ readonly type: "snmp";
39
+ readonly protocol = "snmp";
40
+ readonly version: TSnmpVersion;
41
+ readonly community: string;
42
+ sysDescr?: string;
43
+ sysObjectId?: string;
44
+ sysName?: string;
45
+ sysLocation?: string;
46
+ sysContact?: string;
47
+ sysUpTime?: number;
48
+ constructor(device: TDeviceReference, port: number, options?: ISnmpFeatureOptions);
49
+ protected doConnect(): Promise<void>;
50
+ protected doDisconnect(): Promise<void>;
51
+ /**
52
+ * Get a single OID value
53
+ */
54
+ get(oid: string): Promise<ISnmpVarbind>;
55
+ /**
56
+ * Get multiple OID values
57
+ */
58
+ getMultiple(oids: string[]): Promise<ISnmpVarbind[]>;
59
+ /**
60
+ * Get next OID in MIB tree
61
+ */
62
+ getNext(oid: string): Promise<ISnmpVarbind>;
63
+ /**
64
+ * Walk a subtree of the MIB
65
+ */
66
+ walk(baseOid: string): Promise<ISnmpVarbind[]>;
67
+ /**
68
+ * Bulk get (SNMPv2c/v3)
69
+ */
70
+ getBulk(oids: string[], nonRepeaters?: number, maxRepetitions?: number): Promise<ISnmpVarbind[]>;
71
+ /**
72
+ * Set an OID value
73
+ */
74
+ set(oid: string, type: number, value: unknown): Promise<ISnmpVarbind>;
75
+ /**
76
+ * Get all system info OIDs
77
+ */
78
+ getSystemInfo(): Promise<{
79
+ sysDescr?: string;
80
+ sysObjectId?: string;
81
+ sysName?: string;
82
+ sysLocation?: string;
83
+ sysContact?: string;
84
+ sysUpTime?: number;
85
+ }>;
86
+ getFeatureInfo(): ISnmpFeatureInfo;
87
+ static fromDiscovery(device: TDeviceReference, port: number, metadata: Record<string, unknown>): SnmpFeature;
88
+ }
@@ -0,0 +1,175 @@
1
+ /**
2
+ * SNMP Feature
3
+ * Provides SNMP query capability for network management
4
+ */
5
+ import { Feature } from './feature.abstract.js';
6
+ /**
7
+ * SNMP Feature - provides SNMP query capability
8
+ *
9
+ * Allows querying devices via SNMP for monitoring and management.
10
+ * Many network devices (printers, switches, UPS) support SNMP.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const snmp = device.getFeature<SnmpFeature>('snmp');
15
+ * if (snmp) {
16
+ * const sysDescr = await snmp.get('1.3.6.1.2.1.1.1.0');
17
+ * console.log(`System: ${sysDescr.value}`);
18
+ *
19
+ * const interfaces = await snmp.walk('1.3.6.1.2.1.2.2.1');
20
+ * console.log(`Found ${interfaces.length} interface entries`);
21
+ * }
22
+ * ```
23
+ */
24
+ export class SnmpFeature extends Feature {
25
+ type = 'snmp';
26
+ protocol = 'snmp';
27
+ // Configuration
28
+ version;
29
+ community;
30
+ // System info (populated after connect)
31
+ sysDescr;
32
+ sysObjectId;
33
+ sysName;
34
+ sysLocation;
35
+ sysContact;
36
+ sysUpTime;
37
+ constructor(device, port, options) {
38
+ super(device, port ?? 161, options);
39
+ this.version = options?.version ?? 'v2c';
40
+ this.community = options?.community ?? 'public';
41
+ }
42
+ // ============================================================================
43
+ // Connection
44
+ // ============================================================================
45
+ async doConnect() {
46
+ // Test connection by getting system description
47
+ try {
48
+ const result = await this.get('1.3.6.1.2.1.1.1.0'); // sysDescr
49
+ if (result) {
50
+ this.sysDescr = String(result.value);
51
+ }
52
+ }
53
+ catch {
54
+ // Connection test failed
55
+ throw new Error('SNMP connection failed');
56
+ }
57
+ }
58
+ async doDisconnect() {
59
+ // SNMP is connectionless, nothing to disconnect
60
+ }
61
+ // ============================================================================
62
+ // SNMP Operations
63
+ // ============================================================================
64
+ /**
65
+ * Get a single OID value
66
+ */
67
+ async get(oid) {
68
+ // This would use the SNMP library to perform the query
69
+ // Placeholder implementation
70
+ return {
71
+ oid,
72
+ type: 0,
73
+ value: null,
74
+ };
75
+ }
76
+ /**
77
+ * Get multiple OID values
78
+ */
79
+ async getMultiple(oids) {
80
+ const results = [];
81
+ for (const oid of oids) {
82
+ results.push(await this.get(oid));
83
+ }
84
+ return results;
85
+ }
86
+ /**
87
+ * Get next OID in MIB tree
88
+ */
89
+ async getNext(oid) {
90
+ // Placeholder
91
+ return {
92
+ oid,
93
+ type: 0,
94
+ value: null,
95
+ };
96
+ }
97
+ /**
98
+ * Walk a subtree of the MIB
99
+ */
100
+ async walk(baseOid) {
101
+ const results = [];
102
+ // This would iterate through the MIB tree using getNext
103
+ return results;
104
+ }
105
+ /**
106
+ * Bulk get (SNMPv2c/v3)
107
+ */
108
+ async getBulk(oids, nonRepeaters = 0, maxRepetitions = 10) {
109
+ if (this.version === 'v1') {
110
+ throw new Error('getBulk not supported in SNMPv1');
111
+ }
112
+ // Placeholder
113
+ return [];
114
+ }
115
+ /**
116
+ * Set an OID value
117
+ */
118
+ async set(oid, type, value) {
119
+ // Placeholder
120
+ return {
121
+ oid,
122
+ type,
123
+ value,
124
+ };
125
+ }
126
+ // ============================================================================
127
+ // System Info
128
+ // ============================================================================
129
+ /**
130
+ * Get all system info OIDs
131
+ */
132
+ async getSystemInfo() {
133
+ const oids = [
134
+ '1.3.6.1.2.1.1.1.0', // sysDescr
135
+ '1.3.6.1.2.1.1.2.0', // sysObjectID
136
+ '1.3.6.1.2.1.1.3.0', // sysUpTime
137
+ '1.3.6.1.2.1.1.4.0', // sysContact
138
+ '1.3.6.1.2.1.1.5.0', // sysName
139
+ '1.3.6.1.2.1.1.6.0', // sysLocation
140
+ ];
141
+ const results = await this.getMultiple(oids);
142
+ return {
143
+ sysDescr: results[0]?.value,
144
+ sysObjectId: results[1]?.value,
145
+ sysUpTime: results[2]?.value,
146
+ sysContact: results[3]?.value,
147
+ sysName: results[4]?.value,
148
+ sysLocation: results[5]?.value,
149
+ };
150
+ }
151
+ // ============================================================================
152
+ // Serialization
153
+ // ============================================================================
154
+ getFeatureInfo() {
155
+ return {
156
+ ...this.getBaseFeatureInfo(),
157
+ type: 'snmp',
158
+ version: this.version,
159
+ community: this.version !== 'v3' ? this.community : undefined,
160
+ sysDescr: this.sysDescr,
161
+ sysName: this.sysName,
162
+ sysLocation: this.sysLocation,
163
+ };
164
+ }
165
+ // ============================================================================
166
+ // Static Factory
167
+ // ============================================================================
168
+ static fromDiscovery(device, port, metadata) {
169
+ return new SnmpFeature(device, port ?? 161, {
170
+ version: metadata.version ?? 'v2c',
171
+ community: metadata.community ?? 'public',
172
+ });
173
+ }
174
+ }
175
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS5zbm1wLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvZmVhdHVyZXMvZmVhdHVyZS5zbm1wLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSxPQUFPLEVBQXlCLE1BQU0sdUJBQXVCLENBQUM7QUFzQnZFOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sT0FBTyxXQUFZLFNBQVEsT0FBTztJQUN0QixJQUFJLEdBQUcsTUFBZSxDQUFDO0lBQ3ZCLFFBQVEsR0FBRyxNQUFNLENBQUM7SUFFbEMsZ0JBQWdCO0lBQ0EsT0FBTyxDQUFlO0lBQ3RCLFNBQVMsQ0FBUztJQUVsQyx3Q0FBd0M7SUFDakMsUUFBUSxDQUFVO0lBQ2xCLFdBQVcsQ0FBVTtJQUNyQixPQUFPLENBQVU7SUFDakIsV0FBVyxDQUFVO0lBQ3JCLFVBQVUsQ0FBVTtJQUNwQixTQUFTLENBQVU7SUFFMUIsWUFDRSxNQUF3QixFQUN4QixJQUFZLEVBQ1osT0FBNkI7UUFFN0IsS0FBSyxDQUFDLE1BQU0sRUFBRSxJQUFJLElBQUksR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxFQUFFLE9BQU8sSUFBSSxLQUFLLENBQUM7UUFDekMsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLEVBQUUsU0FBUyxJQUFJLFFBQVEsQ0FBQztJQUNsRCxDQUFDO0lBRUQsK0VBQStFO0lBQy9FLGFBQWE7SUFDYiwrRUFBK0U7SUFFckUsS0FBSyxDQUFDLFNBQVM7UUFDdkIsZ0RBQWdEO1FBQ2hELElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsV0FBVztZQUMvRCxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUNYLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFL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
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Switch Feature
3
+ * Provides binary on/off control for smart switches, outlets, etc.
4
+ */
5
+ import { Feature, type TDeviceReference } from './feature.abstract.js';
6
+ import type { IFeatureOptions } from '../interfaces/feature.interfaces.js';
7
+ import type { TSwitchProtocol, ISwitchCapabilities, ISwitchState, ISwitchFeatureInfo, ISwitchProtocolClient } from '../interfaces/smarthome.interfaces.js';
8
+ /**
9
+ * Options for creating a SwitchFeature
10
+ */
11
+ export interface ISwitchFeatureOptions extends IFeatureOptions {
12
+ /** Protocol type */
13
+ protocol: TSwitchProtocol;
14
+ /** Entity ID (for Home Assistant) */
15
+ entityId: string;
16
+ /** Protocol client for controlling the switch */
17
+ protocolClient: ISwitchProtocolClient;
18
+ /** Device class */
19
+ deviceClass?: 'outlet' | 'switch';
20
+ }
21
+ /**
22
+ * Switch Feature - binary on/off control
23
+ *
24
+ * Protocol-agnostic: works with Home Assistant, MQTT, Tasmota, Tuya, etc.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const sw = device.getFeature<SwitchFeature>('switch');
29
+ * if (sw) {
30
+ * await sw.turnOn();
31
+ * await sw.toggle();
32
+ * console.log(`Switch is ${sw.isOn ? 'on' : 'off'}`);
33
+ * }
34
+ * ```
35
+ */
36
+ export declare class SwitchFeature extends Feature {
37
+ readonly type: "switch";
38
+ readonly protocol: TSwitchProtocol;
39
+ /** Entity ID (e.g., "switch.living_room") */
40
+ readonly entityId: string;
41
+ /** Capabilities */
42
+ readonly capabilities: ISwitchCapabilities;
43
+ /** Current state */
44
+ protected _isOn: boolean;
45
+ /** Protocol client for controlling the switch */
46
+ private protocolClient;
47
+ constructor(device: TDeviceReference, port: number, options: ISwitchFeatureOptions);
48
+ /**
49
+ * Get current on/off state (cached)
50
+ */
51
+ get isOn(): boolean;
52
+ protected doConnect(): Promise<void>;
53
+ protected doDisconnect(): Promise<void>;
54
+ /**
55
+ * Turn on the switch
56
+ */
57
+ turnOn(): Promise<void>;
58
+ /**
59
+ * Turn off the switch
60
+ */
61
+ turnOff(): Promise<void>;
62
+ /**
63
+ * Toggle the switch
64
+ */
65
+ toggle(): Promise<void>;
66
+ /**
67
+ * Refresh state from the device
68
+ */
69
+ refreshState(): Promise<ISwitchState>;
70
+ /**
71
+ * Update state from external source (e.g., state change event)
72
+ */
73
+ updateState(state: ISwitchState): void;
74
+ getFeatureInfo(): ISwitchFeatureInfo;
75
+ }