Skip to content

Commit

Permalink
Merge pull request #66 from krzysztofsk/automatic-calibration
Browse files Browse the repository at this point in the history
Automatic calibration
  • Loading branch information
PiotrMachowski authored Oct 24, 2020
2 parents 3a977c5 + a9de18f commit 10ae256
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 30 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ This card enables you to specify a target or start a zoned cleanup using live or
| `map_image` | `string` | `False` | - | Path to image of map |
| `map_camera` | `string` | `False` | - | ID of map camera entity (for map without root on a vacuum use [this](https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor) integration) |
| `camera_refresh_interval` | `integer` | `False` | 5 | Update interval for map camera in seconds |
| `calibration_points` | `list` | `True` | - | Pairs of coordinates: in vacuum system and on map image. See: [Calibration](#calibration) |
| `camera_calibration` | `boolean` | `False` | - | Automatic calibration if camera entity provides `calibration_points` attribute |
| `calibration_points` | `list` | `False` | - | Pairs of coordinates: in vacuum system and on map image. See: [Calibration](#calibration) |
| `zones` | `list` | `False` | Empty | List of predefined zones |
| `modes` | `list` | `False` | `[go_to_target, zoned_cleanup, predefined_zones]` | List of displayed modes. Possible values: `go_to_target`, `zoned_cleanup`, `predefined_zones` |
| `default_mode` | `string` | `False` | - | Default selected mode. Possible values: `go_to_target`, `zoned_cleanup`, `predefined_zones` |
Expand Down
82 changes: 53 additions & 29 deletions dist/xiaomi-vacuum-map-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class XiaomiVacuumMapCard extends LitElement {
this.vacuumZonedCleanupRepeats = 1;
this.currPoint = {x: null, y: null};
this.outdatedConfig = false;
this.missingCameraAttribute = false;
}

static get properties() {
Expand Down Expand Up @@ -83,36 +84,41 @@ class XiaomiVacuumMapCard extends LitElement {
this._config = config;
return;
}
if (!config.calibration_points || !Array.isArray(config.calibration_points)) {
throw new Error("Missing configuration: calibration_points");
}
if (config.calibration_points.length !== 3) {
throw new Error("Exactly 3 calibration_points required");
}
for (const calibration_point of config.calibration_points) {
if (calibration_point.map === null) {
throw new Error("Missing configuration: calibration_points.map");
}
if (calibration_point.map.x === null) {
throw new Error("Missing configuration: calibration_points.map.x");
if (!config.camera_calibration) {
if (!config.calibration_points || !Array.isArray(config.calibration_points)) {
throw new Error("Missing configuration: calibration_points or camera_calibration");
}
if (calibration_point.map.y === null) {
throw new Error("Missing configuration: calibration_points.map.y");
if (config.calibration_points.length !== 3) {
throw new Error("Exactly 3 calibration_points required");
}
if (calibration_point.vacuum === null) {
throw new Error("Missing configuration: calibration_points.vacuum");
}
if (calibration_point.vacuum.x === null) {
throw new Error("Missing configuration: calibration_points.vacuum.x");
for (const calibration_point of config.calibration_points) {
if (calibration_point.map === null) {
throw new Error("Missing configuration: calibration_points.map");
}
if (calibration_point.map.x === null) {
throw new Error("Missing configuration: calibration_points.map.x");
}
if (calibration_point.map.y === null) {
throw new Error("Missing configuration: calibration_points.map.y");
}
if (calibration_point.vacuum === null) {
throw new Error("Missing configuration: calibration_points.vacuum");
}
if (calibration_point.vacuum.x === null) {
throw new Error("Missing configuration: calibration_points.vacuum.x");
}
if (calibration_point.vacuum.y === null) {
throw new Error("Missing configuration: calibration_points.vacuum.y");
}
}
if (calibration_point.vacuum.y === null) {
throw new Error("Missing configuration: calibration_points.vacuum.y");

this.updateCoordinates(config)
} else {
if (!config.map_camera) {
throw new Error("Invalid configuration: map_camera is required for camera_calibration");
}
}
const p1 = this.getCalibrationPoint(config, 0);
const p2 = this.getCalibrationPoint(config, 1);
const p3 = this.getCalibrationPoint(config, 2);
this.coordinatesConverter = new CoordinatesConverter(p1, p2, p3);


if (config.modes) {
if (!Array.isArray(config.modes) || config.modes.length < 1 || config.modes.length > 3) {
Expand Down Expand Up @@ -157,6 +163,13 @@ class XiaomiVacuumMapCard extends LitElement {
this._config = config;
}

updateCoordinates(config) {
const p1 = this.getCalibrationPoint(config, 0);
const p2 = this.getCalibrationPoint(config, 1);
const p3 = this.getCalibrationPoint(config, 2);
this.coordinatesConverter = new CoordinatesConverter(p1, p2, p3);
}

getConfigurationMigration(config) {
const diffX = config.reference_point.x - config.base_position.x;
const diffY = config.reference_point.y - config.base_position.y;
Expand Down Expand Up @@ -235,7 +248,12 @@ class XiaomiVacuumMapCard extends LitElement {
@touchmove="${e => this.onTouchMove(e)}" />
</div>
</div>
<div class="dropdownWrapper">
${this.missingCameraAttribute ?
html`<div style="padding: 5px;">
<h3>Your camera entity is not providing calibration_points</h3>
<p>Enable calibration_points in camera entity or disable camera_calibration</p>
</div>` :
html`<div class="dropdownWrapper">
<paper-dropdown-menu label="${texts[this._language][mode]}" @value-changed="${e => this.modeSelected(e)}" class="vacuumDropdown" selected="${this.defaultMode}">
<paper-listbox slot="dropdown-content" class="dropdown-content" selected="${this.defaultMode}">
${modesDropdown}
Expand All @@ -246,9 +264,8 @@ class XiaomiVacuumMapCard extends LitElement {
<span id="increaseButton" hidden><mwc-button @click="${() => this.vacuumZonedIncreaseButton()}">${texts[this._language][repeats]} ${this.vacuumZonedCleanupRepeats}</mwc-button></span>
<mwc-button class="vacuumRunButton" @click="${() => this.vacuumStartButton(true)}">${texts[this._language][run]}</mwc-button>
</p>
<div id="toast"><div id="img"><ha-icon icon="mdi:check" style="vertical-align: center"></ha-icon></div><div id="desc">${texts[this._language][confirmation]}</div></div>
</ha-card>
`;
<div id="toast"><div id="img"><ha-icon icon="mdi:check" style="vertical-align: center"></ha-icon></div><div id="desc">${texts[this._language][confirmation]}</div></div>`}
</ha-card>`;
if (this.getMapImage()) {
this.calculateScale();
}
Expand Down Expand Up @@ -673,6 +690,13 @@ class XiaomiVacuumMapCard extends LitElement {
}).then(val => {
const {content_type: contentType, content} = val;
this.map_image = `data:${contentType};base64, ${content}`;
if (this._config.camera_calibration) {
if (!this._hass.states[this._config.map_camera].attributes.calibration_points) {
this.missingCameraAttribute = true;
} else {
this.updateCoordinates(this._hass.states[this._config.map_camera].attributes)
}
}
this.requestUpdate();
})
}
Expand Down

0 comments on commit 10ae256

Please sign in to comment.