Enhance project structure and testing capabilities

- Updated .dockerignore to include additional logs and IDE files, improving Docker build efficiency.
- Added .eslintrc.json for TypeScript linting configuration, ensuring code quality and consistency.
- Refactored Dockerfile to streamline the build process and utilize a slimmer Node.js image.
- Introduced jest-resolver.cjs and jest.setup.js for improved Jest testing configuration and setup.
- Updated jest.config.js to support ESM and added new test patterns for better test organization.
- Enhanced TypeScript schemas to include new device types (media_player, fan, lock, vacuum, scene, script, camera) for comprehensive validation.
- Added unit tests for device schemas and Home Assistant connection, improving test coverage and reliability.
- Updated README.md with new testing instructions and device control examples, enhancing user guidance.
This commit is contained in:
jango-blockchained
2024-12-17 15:07:40 +01:00
parent 7610147a19
commit ada5ea4646
30 changed files with 2385 additions and 130 deletions

View File

@@ -1,7 +1,21 @@
import { z } from "zod";
export const DomainSchema = z.enum(["light", "climate", "alarm_control_panel", "cover", "switch", "contact"]);
export const DomainSchema = z.enum([
"light",
"climate",
"alarm_control_panel",
"cover",
"switch",
"contact",
"media_player",
"fan",
"lock",
"vacuum",
"scene",
"script",
"camera"
]);
// Generic list request schema
@@ -79,4 +93,137 @@ export const DeviceSchema = z.object({
export const ListDevicesResponseSchema = z.object({
_meta: z.object({}).optional(),
devices: z.array(DeviceSchema)
});
// Media Player
export const MediaPlayerAttributesSchema = z.object({
volume_level: z.number().optional(),
is_volume_muted: z.boolean().optional(),
media_content_id: z.string().optional(),
media_content_type: z.string().optional(),
media_duration: z.number().optional(),
media_position: z.number().optional(),
media_title: z.string().optional(),
source: z.string().optional(),
source_list: z.array(z.string()).optional(),
supported_features: z.number().optional(),
});
export const MediaPlayerSchema = z.object({
entity_id: z.string(),
state: z.string(),
state_attributes: MediaPlayerAttributesSchema,
});
// Fan
export const FanAttributesSchema = z.object({
percentage: z.number().optional(),
preset_mode: z.string().optional(),
preset_modes: z.array(z.string()).optional(),
oscillating: z.boolean().optional(),
direction: z.string().optional(),
supported_features: z.number().optional(),
});
export const FanSchema = z.object({
entity_id: z.string(),
state: z.string(),
state_attributes: FanAttributesSchema,
});
// Lock
export const LockAttributesSchema = z.object({
code_format: z.string().optional(),
changed_by: z.string().optional(),
locked: z.boolean(),
supported_features: z.number().optional(),
});
export const LockSchema = z.object({
entity_id: z.string(),
state: z.string(),
state_attributes: LockAttributesSchema,
});
// Vacuum
export const VacuumAttributesSchema = z.object({
battery_level: z.number().optional(),
fan_speed: z.string().optional(),
fan_speed_list: z.array(z.string()).optional(),
status: z.string().optional(),
supported_features: z.number().optional(),
});
export const VacuumSchema = z.object({
entity_id: z.string(),
state: z.string(),
state_attributes: VacuumAttributesSchema,
});
// Scene
export const SceneAttributesSchema = z.object({
entity_id: z.array(z.string()).optional(),
supported_features: z.number().optional(),
});
export const SceneSchema = z.object({
entity_id: z.string(),
state: z.string(),
state_attributes: SceneAttributesSchema,
});
// Script
export const ScriptAttributesSchema = z.object({
last_triggered: z.string().optional(),
mode: z.string().optional(),
variables: z.record(z.any()).optional(),
supported_features: z.number().optional(),
});
export const ScriptSchema = z.object({
entity_id: z.string(),
state: z.string(),
state_attributes: ScriptAttributesSchema,
});
// Camera
export const CameraAttributesSchema = z.object({
motion_detection: z.boolean().optional(),
frontend_stream_type: z.string().optional(),
supported_features: z.number().optional(),
});
export const CameraSchema = z.object({
entity_id: z.string(),
state: z.string(),
state_attributes: CameraAttributesSchema,
});
// Response schemas for new devices
export const ListMediaPlayersResponseSchema = z.object({
media_players: z.array(MediaPlayerSchema),
});
export const ListFansResponseSchema = z.object({
fans: z.array(FanSchema),
});
export const ListLocksResponseSchema = z.object({
locks: z.array(LockSchema),
});
export const ListVacuumsResponseSchema = z.object({
vacuums: z.array(VacuumSchema),
});
export const ListScenesResponseSchema = z.object({
scenes: z.array(SceneSchema),
});
export const ListScriptsResponseSchema = z.object({
scripts: z.array(ScriptSchema),
});
export const ListCamerasResponseSchema = z.object({
cameras: z.array(CameraSchema),
});