olahellgren / home-assistant-sensor-widget-scriptable Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Sometimes sensor values have loads of digits which does not provide any value for the human eye (e.g. solar production 3.122999 kW)
How can we add a rounding feature to set how many decimals the sensors should show?
Describe the bug
Some of the text gets truncated and I can't see it, I have messed around with the padding but with my limited knowledge with this programing I am stuck. Any ideas on how to show the full # figure, see attached screenshot, the top sensor data isn't showing all the numbers. Doesn't happen all the time and then at the bottom it show a number of digits, don't know why at the top it won't show all the digits sometimes but at the bottom it is. Weird.
Here is my file info minus my home data key & passwords etc...
const hassUrl = "https://.ui.nabu.casa"
const hassToken = ""
const widgetTitlesAndSensors = [
"Daily Energy Usage",
"sensor.daily_usage",
"Daily Solar Production",
"sensor.daily_production",
"Daily From Grid",
"sensor.daily_from_grid",
"Daily To Grid",
"sensor.daily_to_grid",
"Daily NET Production",
"sensor.daily_net_production",
"Monthly To Grid",
"sensor.monthly_to_grid",
"Forecast Tomorrow",
"sensor.energy_production_tomorrow",
"Forecast Rest of Day",
"sensor.energy_production_today_remaining"
]
const titleText = "SOLAR PANELS"
const backgroundColorStart = '#049cdb'
const backgroundColorEnd = '#0180c8'
const textColor = '#ffffff'
const sensorFontAndImageSize = 13
const titleFontAndImageSize = 13
const padding = 13
const maxNoOfSensors = 8
const states = await fetchAllStates()
const widget = new ListWidget()
const iconSymbolMap = {
"mdi:calendar": "calendar"
}
const unitSymbolMap = {
"default": "sun.max",
"power": "bolt.fill",
"energy": "bolt.fill",
}
setupBackground(widget)
const mainLayout = widget.addStack()
mainLayout.layoutVertically()
const titleStack = mainLayout.addStack()
titleStack.topAlignContent()
setupTitle(titleStack, titleText, unitSymbolMap.default)
mainLayout.addSpacer(0)
const sensorStack = mainLayout.addStack()
sensorStack.layoutVertically()
sensorStack.centerAlignContent()
widgetTitlesAndSensors.forEach(entry => {
if (getState(states, entry)) {
addSensor(sensorStack, entry)
} else {
setupTitle(sensorStack, entry)
}
})
Script.setWidget(widget)
Script.complete()
widget.presentSmall()
function setupBackground() {
const bGradient = new LinearGradient()
bGradient.colors = [new Color(backgroundColorStart), new Color(backgroundColorEnd)]
bGradient.locations = [0,1]
widget.backgroundGradient = bGradient
widget.setPadding(padding, padding, padding, padding)
widget.spacing = 4
}
function setupTitle(widget, titleText, icon) {
let titleStack = widget.addStack()
titleStack.cornerRadius = 4
titleStack.setPadding(3, 0, 0, 25)
if (icon) {
let wImage = titleStack.addImage(SFSymbol.named(icon).image)
wImage.imageSize = new Size(titleFontAndImageSize, titleFontAndImageSize)
titleStack.addSpacer(5)
}
let wTitle = titleStack.addText(titleText)
wTitle.font = Font.semiboldRoundedSystemFont(titleFontAndImageSize)
wTitle.textColor = Color.white()
}
function addSensorValues(sensorStack, hassSensors) {
hassSensors.forEach(sensor => {
addSensor(sensorStack, sensor)
})
}
function getSymbolForSensor(sensor) {
if (iconSymbolMap[sensor.attributes.icon]) {
return iconSymbolMap[sensor.attributes.icon]
} else if (unitSymbolMap[sensor.attributes.device_class]) {
return unitSymbolMap[sensor.attributes.device_class]
} else {
return unitSymbolMap.default
}
}
function addSensor(sensorStack, entityId) {
const sensor = getState(states, entityId)
const row = sensorStack.addStack()
row.setPadding(0, 0, 0, 0)
row.layoutHorizontally()
const icon = row.addStack()
icon.setPadding(0, 0, 0, 3)
const sfSymbol = getSymbolForSensor(sensor)
const sf = SFSymbol.named(sfSymbol)
const imageNode = icon.addImage(sf.image)
imageNode.imageSize = new Size(sensorFontAndImageSize, sensorFontAndImageSize)
const value = row.addStack()
value.setPadding(0, 0, 0, 5)
const valueText = setSensorText(value, sensor)
valueText.font = Font.mediumRoundedSystemFont(sensorFontAndImageSize)
valueText.textColor = new Color(textColor)
if (sensor.attributes.unit_of_measurement) {
const unit = row.addStack()
const unitText = unit.addText(sensor.attributes.unit_of_measurement)
unitText.font = Font.mediumSystemFont(sensorFontAndImageSize)
unitText.textColor = new Color(textColor)
}
}
function setSensorText(value, sensor) {
if (sensor.attributes.device_class === "moisture") {
return sensor.state === "on" ? value.addText("Wet") : value.addText("Dry")
} else {
return value.addText(sensor.state)
}
}
function addEmptyRow() {
const row = widget.addStack()
row.layoutHorizontally()
const t = row.addText(' ')
t.font = Font.mediumSystemFont(sensorFontAndImageSize)
}
async function fetchAllStates() {
let req = new Request(${hassUrl}/api/states
)
req.headers = {
"Authorization": Bearer ${hassToken}
,
"content-type": "application/json"
}
return await req.loadJSON();
}
function getState(states, entityId) {
return states.filter(state => state.entity_id === entityId)[0]
}
Maybe I'm stupid but I don't understand
Nothing happens.
const hassUrl = "http://192.168.50.97:8123"
const hassToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkZmIwMjJkNzJkZTE0Y2VhOTRkZGE3OWE4NzY5YzEzZCIsImlhdCI6MTcxNDMzNTA2OSwiZXhwIjoyMDI5Njk1MDY.yRr6ju87ycwhR8RsF3em9S2SXEVPCaZ-tH5VG-Wdpyo"
const widgetTitlesAndSensors = [
"sensor.sun_next_noon",
]
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Describe the solution you'd like
A clear and concise description of what you want to happen.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
Is your feature request related to a problem? Please describe.
I have a thermostat with 6 useful datapoints hidden inside the attributes
Describe the solution you'd like
Allow attribute.sensor.sensorname.attributename
Additional context
I know I can create template sensors in homeassistant, but it's potentially a lot of legwork and there have been attempts in lovelace to avoid users having to take these steps.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.