So I just got one of those analogue lab incubators you might remember from high school, and want to use it to ferment things. I’ve been testing the different gas marks (it’s electric but that’s all i can think to call them, since it’s analog? idk) to see what temperature they correspond to. I decided I wanted a visual representation on my dashboard of what temperature the bluetooth thermometer I put inside was reading. This could technically be a static image but where’s the fun in that?
Anyway, the canvas gauge card [as of v0.4.1] allows EITHER string labels equally spaced throughout the gauge range OR numerical labels correctly labeling the gauge. But what if you want to place arbitrary labels at arbitrary values?
WELL it turns out that you can pass arrays to specify the name, label color, and tick color, and “transparent” is a valid color
So, with the help of the config template card’s javascript functionality to keep you from having to write out a hundred-entry long list, it turns out you can do just that!
YAML below.
NOTE: the reason i have different functions for dealing with an array of colors vs an array of labels instead of just having the choice to fill hidden values with ''
or 'transparent'
be another input is that the card/canvasgauge project has a bug where the gauge border will be the same color as the first of the ticks, so you gotta inject a black one at the beginning of the array or it’ll give you a transparent ring instead. Haven’t checked if separately specifying the gauge border color would fix it, that’s not really relevant to this project
NOTE 2: Javascript isn’t my main programming language, so i’m sure this could be written better. If you don’t like it, write a better one
type: custom:config-template-card
variables:
TEMPERATURE: states['sensor.ble_temperature_cc3238313892'].state
_scaleMin: 0
_scaleMax: 100
tickLocations:
- 12
- 22
- 70
- 92.7
tickNames: ['99','nope','3','what'] //you can use javascript arrays as well but unfortunately line breaks still don't work
tickColors:
- 'red'
- 'purple'
- 'blue'
- 'green'
nameArray: |
(nameArray, locArray, gaugeMin, gaugeMax) => {
// nameArray and locArray must be the same length
// gaugeMin and gaugeMax should be integers or floats
var labelArray = locArray.map(function(e, i) {
return [e, nameArray[i]];
});
var limits = +((gaugeMax - gaugeMin).toFixed(1));
limits *= 10 //allows us to have 1 decimal of precision
let arr = new Array(parseInt(limits));
arr.fill("")
labelArray.forEach(function (item) {
arr[10*(item[0]-gaugeMin)]=item[1];
});
return arr;
}
colorArray: |
(nameArray, locArray, gaugeMin, gaugeMax) => {
// nameArray and locArray must be the same length
// gaugeMin and gaugeMax should be integers or floats
var labelArray = locArray.map(function(e, i) {
return [e, nameArray[i]];
});
var limits = +((gaugeMax - gaugeMin).toFixed(1));
limits *= 10 //allows us to have 1 decimal of precision
let arr = new Array(parseInt(limits));
arr.fill("transparent")
labelArray.forEach(function (item) {
arr[(10*item[0])-(10*gaugeMin)]=item[1];
});
arr[0]="black";
arr[arr.length - 1]="black";
return arr;
}
entities:
- sensor.ble_temperature_cc3238313892
card:
type: custom:mod-card
card:
type: custom:canvas-gauge-card
entity: sensor.ble_temperature_cc3238313892
card_height: 125
gauge:
type: radial-gauge
title: null
width: 220
height: 125
minValue: ${_scaleMin}
maxValue: ${_scaleMax}
valueBox: false
fontNumbersSize: 30
valueDec: 1
valueText: ${TEMPERATURE.toString()+'°'+'F'}
majorTicks: ${ nameArray(tickNames,tickLocations,_scaleMin,_scaleMax) }
colorMajorTicks: ${ colorArray(tickColors,tickLocations,_scaleMin,_scaleMax) }
colorNumbers: ${ colorArray(tickColors,tickLocations,_scaleMin,_scaleMax)}
minorTicks: null
strokeTicks: true
animation: false
highlightsLineCap: round
highlights:
- from: 42
to: 53
color: orange
- from: 75.2
to: ${_scaleMax}
color: pink
borders: false
card_mod:
style: |
canvas-gauge-card {
box-shadow: none !important;
background: none !important;
}