Skip to content

Commit

Permalink
Trying to get Host Names in the Spech if possible.
Browse files Browse the repository at this point in the history
  • Loading branch information
CCOSTAN committed Jul 6, 2017
1 parent a66906b commit 6a1cd3a
Show file tree
Hide file tree
Showing 4 changed files with 867 additions and 27 deletions.
2 changes: 1 addition & 1 deletion automation/Speech/new_device.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
action:
- service: script.speech_engine
data_template:
NewDevice: "There has been a new device detected on the network. Be sure to appropriately catagorize it within Circle."
NewDevice: "There has been a new device detected on the network. Be sure to appropriately catagorize {{trigger.event.data.host_name}} within Circle."

##############################################################################
2 changes: 1 addition & 1 deletion floorplan.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Alarm Panel
image: /local/custom_ui/floorplan/floorplan.svg
stylesheet: /local/custom_ui/floorplan/floorplan.css
#pan_zoom:
pan_zoom:

groups:

Expand Down
211 changes: 186 additions & 25 deletions www/custom_ui/floorplan/ha-floorplan.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://raw.githubusercontent.com/pkozul/ha-floorplan/master/www/custom_ui/floorplan/svg-pan-zoom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>

<dom-module id="ha-floorplan">

Expand All @@ -15,7 +17,7 @@
overflow: hidden;
}

#debug {
#warnings {
color: #FF851B;
display: none;
}
Expand All @@ -27,7 +29,7 @@
</div>
</template>

<div id="debug">
<div id="warnings">
<ul></ul>
</div>

Expand Down Expand Up @@ -66,15 +68,12 @@
},
config: {
type: Object,
observer: 'configChanged'
},
isLoading: {
type: Boolean,
value: true,
},
showHeader: {
type: Boolean,
value: false,
},
timeDifference: {
type: Number,
value: undefined,
Expand All @@ -87,6 +86,14 @@
type: Array,
value: () => { return []; },
},
IsWarningsEnabled: {
type: Boolean,
value: false,
},
IsPanZoomEnabled: {
type: Boolean,
value: false,
},
},

stopPropagation(e) {
Expand All @@ -97,7 +104,18 @@
this.handleEntities(newHass.states);
},

configChanged: function (newConfig, oldConfig) {
this.IsWarningsEnabled = ((newConfig.warnings === null) || (newConfig.warnings !== undefined));
this.IsPanZoomEnabled = ((newConfig.pan_zoom === null) || (newConfig.pan_zoom !== undefined));
},

onAttached() {
if (!this.config.groups) {
this.isLoading = false;
this.warn(`Cannot find 'groups' in floorplan configuration`);
return;
}

this.hass.connection.socket.addEventListener('message', event => {
var data = JSON.parse(event.data);

Expand Down Expand Up @@ -163,23 +181,31 @@
$(svg).width('100%');
$(svg).css('position', this.instance.isPanel ? 'absolute' : 'relative');

var uniqueId = (new Date()).getTime();

var svgShapes = $(svg).find('*').toArray();

for (var entityGroup of this.instance.config.groups) {
var targetEntityIds = [];
for (var entityId of entityGroup.entities) {
if (entityId.indexOf('group.') == 0) {

// Split out HA entity groups into separate entities
if (entityGroup.groups) {
for (var entityId of entityGroup.groups) {
var group = this.instance.hass.states[entityId];
if (group) {
for (var targetEntityId of group.attributes.entity_id) {
targetEntityIds.push(targetEntityId);
}
}
else {
this.instance.debug(`Cannot find '${entityId}' in HA group configuration`);
this.instance.warn(`Cannot find '${entityId}' in HA group configuration`);
}
}
else {
}

// HA entities treated as is
if (entityGroup.entities) {
for (var entityId of entityGroup.entities) {
targetEntityIds.push(entityId);
}
}
Expand All @@ -204,6 +230,11 @@
};

$(svgShape).find('*').each((i, svgNestedShape) => {
// Ensure that all child elements have an Id.
if (!svgNestedShape.id) {
svgNestedShape.id = uniqueId++;
}

entityConfig.svgShapeConfigs[svgNestedShape.id] = {
svgShapeId: svgNestedShape.id,
svgShape: svgNestedShape,
Expand All @@ -213,7 +244,7 @@
});
}
else {
this.instance.debug(`Cannot find element '${entityId}' in SVG file`);
this.instance.warn(`Cannot find element '${entityId}' in SVG file`);
}
}
}
Expand Down Expand Up @@ -246,10 +277,38 @@
svgShapeConfig.svgShape = newSvgShape[0];

$(newSvgShape).attr('title', 'test');
$(newSvgShape).on('click', this.instance.onShapeClick.bind(this.instance));
$(newSvgShape).on('touchstart', this.instance.onShapeClick.bind(this.instance));

if (this.IsPanZoomEnabled) {
// Touch screen friendlyness!
//var mc = new Hammer(newSvgShape[0]); //went for the custom recognizers
var mc = new Hammer.Manager(newSvgShape[0]);

// Tap recognizer with minimal 2 taps
mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 }));

// Single tap recognizer
mc.add(new Hammer.Tap({ event: 'singletap' }));

// Press recognizer
mc.add(new Hammer.Press({ event: 'press' }));

// We want to recognize this simulatenous, so a quadrupletap will be detected even while a tap has been recognized.
mc.get('doubletap').recognizeWith('singletap');

// We only want to trigger a tap, when we don't have detected a doubletap
mc.get('singletap').requireFailure('doubletap');

mc.on("doubletap", this.instance.onShapeDoubleClick.bind(this.instance));
mc.on("singletap", this.instance.onShapeClick.bind(this.instance));
mc.on("press", this.instance.onShapePress.bind(this.instance));
}
else {
$(newSvgShape).on('click', this.instance.onShapeClick.bind(this.instance));
$(newSvgShape).on('dblclick', this.instance.onShapeDoubleClick.bind(this.instance));
}

$(newSvgShape).css('cursor', 'pointer');
$(newSvgShape).addClass('entity');
$(newSvgShape).addClass('ha-entity');

if ((newSvgShape[0].nodeName === 'text') && (newSvgShape[0].id === entityId)) {
var boundingBox = newSvgShape[0].getBBox();
Expand All @@ -270,12 +329,14 @@
}

// Enable pan / zoom if enabled in config
if ((this.instance.config.pan_zoom === null) || (this.instance.config.pan_zoom !== undefined)) {
if (this.IsPanZoomEnabled) {
svgPanZoom($(newSvg)[0], {
zoomEnabled: true,
controlIconsEnabled: true,
fit: true,
center: true,
dblClickZoomEnabled: false,
customEventsHandler: this.instance.getHammerEventHandlers(),
});
}

Expand Down Expand Up @@ -374,6 +435,8 @@
targetClass = this.assemble(entityConfig.group.class_template, entityState, entities);
}

var originalClasses = this.getArray(svgShapeConfig.clonedSvgShape.classList);

// Get the config for the current state
if (entityConfig.group.states) {
var stateConfig = entityConfig.group.states.find(stateConfig => (stateConfig.state === entityState.state));
Expand All @@ -382,16 +445,22 @@
}

// Remove any other previously-added state classes
for (var otherStateConfig of entityConfig.group.states.filter(otherStateConfig => !stateConfig || (otherStateConfig.state != stateConfig.state))) {
if (otherStateConfig.class && (otherStateConfig.class != 'entity') && $(svgShape).hasClass(otherStateConfig.class)) {
obsoleteClasses.push(otherStateConfig.class);
for (var otherStateConfig of entityConfig.group.states) {
if (!stateConfig || (otherStateConfig.state != stateConfig.state)) {
if (otherStateConfig.class && (otherStateConfig.class != 'ha-entity') && $(svgShape).hasClass(otherStateConfig.class)) {
if (originalClasses.indexOf(otherStateConfig.class) < 0) {
obsoleteClasses.push(otherStateConfig.class);
}
}
}
}
}
else {
for (var otherClassName of this.getArray(svgShape.classList)) {
if ((otherClassName != targetClass) && (otherClassName != 'entity')) {
obsoleteClasses.push(otherClassName);
if ((otherClassName != targetClass) && (otherClassName != 'ha-entity')) {
if (originalClasses.indexOf(otherClassName) < 0) {
obsoleteClasses.push(otherClassName);
}
}
}
}
Expand Down Expand Up @@ -563,6 +632,40 @@
}
},

onShapeDoubleClick(e) {
for (var entityId in this.entityConfigs) {
var entityConfig = this.entityConfigs[entityId];
var svgShapeConfig = entityConfig.svgShapeConfigs[e.target.id];
if (svgShapeConfig) {
if (entityConfig.group.doubleclickaction && entityConfig.group.doubleclickaction.service) {
var domain = window.HAWS.extractDomain(entityId);
this.hass.callService(domain, entityConfig.group.action.service, {
entity_id: entityId
});
} else {
this.fire('hass-more-info', { entityId: svgShapeConfig.entityId });
}
}
}
},

onShapePress(e) {
for (var entityId in this.entityConfigs) {
var entityConfig = this.entityConfigs[entityId];
var svgShapeConfig = entityConfig.svgShapeConfigs[e.target.id];
if (svgShapeConfig) {
if (entityConfig.group.pressaction && entityConfig.group.pressaction.service) {
var domain = window.HAWS.extractDomain(entityId);
this.hass.callService(domain, entityConfig.group.action.service, {
entity_id: entityId
});
} else {
this.fire('hass-more-info', { entityId: svgShapeConfig.entityId });
}
}
}
},

getFill(stateConfig) {
var fill = undefined;

Expand Down Expand Up @@ -625,6 +728,64 @@
return serverMoment;
},

getHammerEventHandlers() {
var eventsHandlers = {
haltEventListeners: ['touchstart', 'touchend', 'touchmove', 'touchleave', 'touchcancel'],
init: (options) => {
var instance = options.instance;
var initialScale = 1;
var pannedX = 0;
var pannedY = 0;

// Init Hammer
// Listen only for pointer and touch events
this.hammer = Hammer(options.svgElement, {
inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput
});

// Enable pinch
this.hammer.get('pinch').set({ enable: true });

// Handle double tap
//this.hammer.on('doubletap', (ev) => {
// instance.zoomIn();
//});

// Handle pan
this.hammer.on('panstart panmove', (ev) => {
// On pan start reset panned variables
if (ev.type === 'panstart') {
pannedX = 0
pannedY = 0
}

// Pan only the difference
instance.panBy({ x: ev.deltaX - pannedX, y: ev.deltaY - pannedY });
pannedX = ev.deltaX;
pannedY = ev.deltaY;
});

// Handle pinch
this.hammer.on('pinchstart pinchmove', (ev) => {
// On pinch start remember initial zoom
if (ev.type === 'pinchstart') {
initialScale = instance.getZoom();
instance.zoom(initialScale * ev.scale);
}
instance.zoom(initialScale * ev.scale);
});

// Prevent moving the page on some devices when panning over SVG
options.svgElement.addEventListener('touchmove', (e) => { e.preventDefault(); });
},

destroy: () => {
this.hammer.destroy();
}
};
return eventsHandlers;
},

getArray(list) {
return Array.isArray(list) ? list : Object.keys(list).map(key => list[key]);
},
Expand All @@ -635,11 +796,11 @@
return func(entity, entities, this.hass, this.config);
},

debug(message) {
if ((this.config.warnings === null) || (this.config.warnings !== undefined)) {
var debug = Polymer.dom(this.$.debug).node;
$(debug).find('ul').append(`<li>${message}</li>`)
$(debug).css('display', 'block');
warn(message) {
if (this.IsWarningsEnabled) {
var warnings = Polymer.dom(this.$.warnings).node;
$(warnings).find('ul').append('<li>${message}</li>')
$(warnings).css('display', 'block');
}
},

Expand Down
Loading

0 comments on commit 6a1cd3a

Please sign in to comment.