No heading arrow on the puck (owner call)

The wedge looked like clutter at badge size; the trail already shows
where the robot is going. Smoke asserts its absence now.
This commit is contained in:
Matysh
2026-07-31 09:46:46 +03:00
parent f5c56d2f8e
commit d2faa070b5
8 changed files with 13 additions and 86 deletions
@@ -1263,21 +1263,6 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
.vacpuck.jump { transition: none; }
.vacpuck.stale { opacity: 0.45; animation: none; }
.vacpuck ha-icon { --mdc-icon-size: calc(var(--puck-size) * 0.68); color: var(--hp-txt); }
.vacwedge {
position: absolute;
inset: 0;
pointer-events: none;
}
.vacwedge::before {
content: '';
position: absolute;
top: -5px;
left: 50%;
margin-left: -3.5px;
border-left: 3.5px solid transparent;
border-right: 3.5px solid transparent;
border-bottom: 6px solid var(--hp-accent);
}
@keyframes vacpulse {
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--hp-accent) 45%, transparent); }
70% { box-shadow: 0 0 0 12px transparent; }
@@ -2133,13 +2118,12 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
</label>
${a.length?B`<div class="rhint">${ti(this._t("vac.cal_maps"),{maps:a.join(", ")})}</div>`:G}
`:G}
</div>`}_vacMapId(t,e){if("default"!==e.mapId)return e.mapId;const i=this._vacEntity(t),s=i?this.hass?.states[i]?.attributes?.selected_map:null;return s?String(s):"default"}_vacSaveMatrix(t,e,i,s){const o=this._serverCfg,n=o?.markers?.find(e=>e.id===t);if(!n)return;const r={...n.vacuum||{}};r.source=e,r.calibration={...r.calibration||{},[i]:s.map(t=>Number(t.toFixed(6)))},n.vacuum=r,this._regSignature="",this._saveConfig(),this.requestUpdate()}_vacAutoCalibrate(t){const e=this._vacSource(t),i=e?Pi(this.hass?.states[e]?.attributes):null;if(!e||!i||i.rooms.length<3)return void this._showToast(this._t("vac.autocal_no_rooms"));const s=this._spaceModel(t.space),o=(s?.rooms||[]).filter(t=>t.name&&t.poly?.length>=3).map(t=>{const e=Ae(t.poly);return{name:t.name,cx:e[0],cy:e[1]}}),n=function(t,e){const i=new Map(e.map(t=>[Ai(t.name),t])),s=[],o=[];for(const e of t){const t=i.get(Ai(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),o.push(e.name))}if(s.length<3)return null;const n=Di(s);return n?{matrix:n,matched:o,residual:Ti(n,s)}:null}(i.rooms,o);n?(n.residual>50&&this._showToast(ti(this._t("vac.autocal_res_warn"),{rooms:String(n.matched.length)})),this._vacSaveMatrix(t.id,e,this._vacMapId(t,i),n.matrix),this._showToast(ti(this._t("vac.autocal_done"),{rooms:String(n.matched.length)}))):this._showToast(this._t("vac.autocal_no_match"))}_vacStartWizard(t){const e=this._vacSource(t),i=e?Pi(this.hass?.states[e]?.attributes):null;e&&i?.pos?(this._markerDialog=null,this._vacCal={markerId:t.id,source:e,mapId:this._vacMapId(t,i),pairs:[]}):this._showToast(this._t("vac.cal_need_pos"))}_vacCalClick(t){const e=this._vacCal;if(!e)return;const i=Pi(this.hass?.states[e.source]?.attributes);if(!i?.pos)return void this._showToast(this._t("vac.cal_need_pos"));const s=this._svgPoint(t),o=[...e.pairs,[[i.pos.x,i.pos.y],[s[0],s[1]]]];if(o.length<3)return void(this._vacCal={...e,pairs:o});const n=Di(o);return n?Ti(n,o)>50&&o.length<4?(this._vacCal={...e,pairs:o},void this._showToast(this._t("vac.cal_res_warn"))):(this._vacSaveMatrix(e.markerId,e.source,e.mapId,n),this._vacCal=null,void this._showToast(this._t("vac.cal_done"))):(this._vacCal={...e,pairs:o.slice(0,-1)},void this._showToast(this._t("vac.cal_degenerate")))}_renderVacuums(t,e){if(this._markup||"decor"===this._mode)return G;const i=[],s=[];for(const o of t){if(o.hidden||!this._isVacDev(o))continue;const t=this._vacSource(o);if(!t)continue;const n=Pi(this.hass?.states[t]?.attributes);if(!n)continue;const r=o.marker?.vacuum?.calibration?.[this._vacMapId(o,n)];if(!r||6!==r.length)continue;const a=this._vacRt.get(o.id),l=a?.moving??!1,c=!l&&a?.endedTs&&Date.now()-a.endedTs<6e5;if(!1!==o.marker?.vacuum?.trail&&(l||c)){const t=n.path||a?.trail||[];if(t.length>1){const e=t.map(([t,e])=>{const[i,s]=Ci(r,t,e);return i.toFixed(1)+","+s.toFixed(1)}).join(" ");s.push(j`<polyline points="${e}"></polyline>`)}}if(!l||!n.pos)continue;const[h,d]=Ci(r,n.pos.x,n.pos.y),p=(h-e.x)/e.w*100,u=(d-e.y)/e.h*100,_=a&&a.lastTs>0&&Date.now()-a.lastTs>6e4,m=null!=n.pos.a?n.pos.a+180*Math.atan2(r[3],r[0])/Math.PI:null,g=o.marker?.icon||o.icon||"mdi:robot-vacuum";i.push(B`<div
</div>`}_vacMapId(t,e){if("default"!==e.mapId)return e.mapId;const i=this._vacEntity(t),s=i?this.hass?.states[i]?.attributes?.selected_map:null;return s?String(s):"default"}_vacSaveMatrix(t,e,i,s){const o=this._serverCfg,n=o?.markers?.find(e=>e.id===t);if(!n)return;const r={...n.vacuum||{}};r.source=e,r.calibration={...r.calibration||{},[i]:s.map(t=>Number(t.toFixed(6)))},n.vacuum=r,this._regSignature="",this._saveConfig(),this.requestUpdate()}_vacAutoCalibrate(t){const e=this._vacSource(t),i=e?Pi(this.hass?.states[e]?.attributes):null;if(!e||!i||i.rooms.length<3)return void this._showToast(this._t("vac.autocal_no_rooms"));const s=this._spaceModel(t.space),o=(s?.rooms||[]).filter(t=>t.name&&t.poly?.length>=3).map(t=>{const e=Ae(t.poly);return{name:t.name,cx:e[0],cy:e[1]}}),n=function(t,e){const i=new Map(e.map(t=>[Ai(t.name),t])),s=[],o=[];for(const e of t){const t=i.get(Ai(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),o.push(e.name))}if(s.length<3)return null;const n=Di(s);return n?{matrix:n,matched:o,residual:Ti(n,s)}:null}(i.rooms,o);n?(n.residual>50&&this._showToast(ti(this._t("vac.autocal_res_warn"),{rooms:String(n.matched.length)})),this._vacSaveMatrix(t.id,e,this._vacMapId(t,i),n.matrix),this._showToast(ti(this._t("vac.autocal_done"),{rooms:String(n.matched.length)}))):this._showToast(this._t("vac.autocal_no_match"))}_vacStartWizard(t){const e=this._vacSource(t),i=e?Pi(this.hass?.states[e]?.attributes):null;e&&i?.pos?(this._markerDialog=null,this._vacCal={markerId:t.id,source:e,mapId:this._vacMapId(t,i),pairs:[]}):this._showToast(this._t("vac.cal_need_pos"))}_vacCalClick(t){const e=this._vacCal;if(!e)return;const i=Pi(this.hass?.states[e.source]?.attributes);if(!i?.pos)return void this._showToast(this._t("vac.cal_need_pos"));const s=this._svgPoint(t),o=[...e.pairs,[[i.pos.x,i.pos.y],[s[0],s[1]]]];if(o.length<3)return void(this._vacCal={...e,pairs:o});const n=Di(o);return n?Ti(n,o)>50&&o.length<4?(this._vacCal={...e,pairs:o},void this._showToast(this._t("vac.cal_res_warn"))):(this._vacSaveMatrix(e.markerId,e.source,e.mapId,n),this._vacCal=null,void this._showToast(this._t("vac.cal_done"))):(this._vacCal={...e,pairs:o.slice(0,-1)},void this._showToast(this._t("vac.cal_degenerate")))}_renderVacuums(t,e){if(this._markup||"decor"===this._mode)return G;const i=[],s=[];for(const o of t){if(o.hidden||!this._isVacDev(o))continue;const t=this._vacSource(o);if(!t)continue;const n=Pi(this.hass?.states[t]?.attributes);if(!n)continue;const r=o.marker?.vacuum?.calibration?.[this._vacMapId(o,n)];if(!r||6!==r.length)continue;const a=this._vacRt.get(o.id),l=a?.moving??!1,c=!l&&a?.endedTs&&Date.now()-a.endedTs<6e5;if(!1!==o.marker?.vacuum?.trail&&(l||c)){const t=n.path||a?.trail||[];if(t.length>1){const e=t.map(([t,e])=>{const[i,s]=Ci(r,t,e);return i.toFixed(1)+","+s.toFixed(1)}).join(" ");s.push(j`<polyline points="${e}"></polyline>`)}}if(!l||!n.pos)continue;const[h,d]=Ci(r,n.pos.x,n.pos.y),p=(h-e.x)/e.w*100,u=(d-e.y)/e.h*100,_=a&&a.lastTs>0&&Date.now()-a.lastTs>6e4,m=o.marker?.icon||o.icon||"mdi:robot-vacuum";i.push(B`<div
class="vacpuck ${a?.jump?"jump":""} ${_?"stale":""}"
style="left:${p}%;top:${u}%"
title=${o.name}
@click=${t=>{t.stopPropagation();const e=this._vacEntity(o);e&&this._openMoreInfo(e)}}>
${null!=m?B`<div class="vacwedge" style="transform:rotate(${m}deg)"></div>`:G}
<ha-icon .icon=${g}></ha-icon>
<ha-icon .icon=${m}></ha-icon>
</div>`)}return i.length||s.length?B`
${s.length?j`<svg class="vactrail" viewBox="${e.x} ${e.y} ${e.w} ${e.h}" preserveAspectRatio="none">${s}</svg>`:G}
${i}`:G}_renderDevice(t,e,i=!0,s=!1){const o=this._pos(t),n=(o.x-e.x)/e.w*100,r=(o.y-e.y)/e.h*100;let a=t.hidden?"":this._stateClass(t);s&&"on"===a&&Fi(this.hass,t)&&(a="");const l=t.hidden?null:this._liveTemp(t),c=t.hidden?null:this._liveHum(t),h=!i||t.virtual||t.hidden?null:Ui(this.hass,t.entities),d=t.marker,p=d?.display||"badge",u=("ripple"===p||"icon_ripple"===p)&&!t.hidden,_=t.primary?this.hass.states[t.primary]:void 0,m="value"!==p||t.hidden?null:null!=l?l+"°":null!=c?c+"%":_&&!isNaN(parseFloat(_.state))?parseFloat(_.state)+(_.attributes?.unit_of_measurement?" "+_.attributes.unit_of_measurement:""):null,g=t.primary?t.primary.split(".")[0]:null,f=this._config?.live_states&&!t.hidden?ci(t.icon,g,_?.attributes?.device_class,_?.state,!!d?.icon):t.icon,v=(d?.controls||[]).filter(_i),b=this._config?.live_states&&!t.hidden?v.length?v.map(t=>hi(this.hass.states[t])).find(t=>t)||null:"light"===g?hi(_):null:null,y=this._config?.live_states&&!t.hidden&&function(t,e,i){return"on"===i&&("siren"===t||"binary_sensor"===t&&!!e&&Si.has(e))}(g,_?.attributes?.device_class,_?.state),w=u&&!t.hidden&&!!t.primary&&$e(this.hass.states[t.primary]?.state),x=Number(d?.size)>0?Number(d.size):1,k=Number(d?.angle)||0,$=Number(d?.ripple_size)>0?Number(d.ripple_size):3,S=[`left:${n}%`,`top:${r}%`];return 1!==x&&S.push(`--dev-scale:${x}`),u&&(S.push(`--ripple-scale:${$}`),d?.ripple_color?S.push(`--ripple-color:${d.ripple_color}`):b&&S.push(`--ripple-color:${b}`)),B`<div