Custom Dark Sky Animated Weather Card

Hi @woody4165, great work. Can you post your latest working js and css files? I’d like to insert first 2 lines for today and tomorrow, and 3 lines for next days at the end. Thanks

Thanks @Mariusthvdb

All is working fine, I will use your way of capitalizing!

@itajackass

This is my actual card

08

and this the code I have used for it thanks to @jusdwy and @Mariusthvdb contribution (hope to haven’t forgot anyone)

dark-sky-weather-card.js

class DarkSkyWeatherCard extends HTMLElement {
  set hass(hass) {
    if (!this.content) {
      const card = document.createElement('ha-card');
      const link = document.createElement('link');
      link.type = 'text/css';
      link.rel = 'stylesheet';
      link.href = '/local/custom_ui/dark-sky-weather-card.css';
      card.appendChild(link);
      this.content = document.createElement('div');
      this.content.className = 'card';
      card.appendChild(this.content);
      this.appendChild(card);
    }

    const getUnit = function (measure) {
      const lengthUnit = hass.config.unit_system.length;
      switch (measure) {
        case 'air_pressure':
          return lengthUnit === 'km' ? 'hPa' : 'mbar';
        case 'length':
          return lengthUnit;
        case 'precipitation':
          return lengthUnit === 'km' ? 'mm' : 'in';
        case 'visibility':
          return lengthUnit === 'km' ? 'm' : 'in';
        default:
          return hass.config.unit_system[measure] || '';
      }
    };

    const transformDayNight = {
      "below_horizon": "night",
      "above_horizon": "day",
    }
    const sunLocation = transformDayNight[hass.states[this.config.entity_sun].state];
    const weatherIcons = {
      'clear-day': 'day',
      'clear-night': 'night',
      'rain': 'rainy-5',
      'snow': 'snowy-6',
      'sleet': 'rainy-6',
      'wind': 'cloudy',
      'fog': 'cloudy',
      'cloudy': 'cloudy',
      'partly-cloudy-day': 'cloudy-day-3',
      'partly-cloudy-night': 'cloudy-night-3',
      'hail': 'rainy-7',
      'lightning': 'thunder',
      'thunderstorm': 'thunder',
      'windy-variant': `cloudy-${sunLocation}-3`,
      'exceptional': '!!',
    }

    const windDirections = [
      'N',
      'NNE',
      'NE',
      'ENE',
      'E',
      'ESE',
      'SE',
      'SSE',
      'S',
      'SSW',
      'SW',
      'WSW',
      'W',
      'WNW',
      'NW',
      'NNW',
      'N'
    ];

    var forecastDate1 = new Date();
    forecastDate1.setDate(forecastDate1.getDate()+1);
    var forecastDate2 = new Date();
    forecastDate2.setDate(forecastDate2.getDate()+2);
    var forecastDate3 = new Date();
    forecastDate3.setDate(forecastDate3.getDate()+3);
    var forecastDate4 = new Date();
    forecastDate4.setDate(forecastDate4.getDate()+4);
    var forecastDate5 = new Date();
    forecastDate5.setDate(forecastDate5.getDate()+5);


    const currentConditions = hass.states[this.config.entity_current_conditions].state;
    const humidity = hass.states[this.config.entity_humidity].state;
    const pressure = Math.round(hass.states[this.config.entity_pressure].state);
    const temperature = Math.round(hass.states[this.config.entity_temperature].state);
    const feelstemperature = Math.round(hass.states[this.config.entity_feelstemp].state);
    const visibility = hass.states[this.config.entity_visibility].state*1000;
    const windBearing = windDirections[(Math.round((hass.states[this.config.entity_wind_bearing].state / 360) * 16))];
    const windSpeed = Math.round(hass.states[this.config.entity_wind_speed].state);

    var sunSetOrRiseA = hass.states[this.config.entity_sun].attributes.next_setting;
    sunSetOrRiseA = new Date(sunSetOrRiseA);
    var sunSetOrRiseIconA = "mdi:weather-sunset-down";
    var sunSetOrRiseB = hass.states[this.config.entity_sun].attributes.next_rising;
    sunSetOrRiseB = new Date(sunSetOrRiseB);
    var sunSetOrRiseIconB = "mdi:weather-sunset-up";
    // A == sunset   B == sunrise

    if ( hass.states[this.config.entity_sun].state == "above_horizon" ) {
        // next is sunset == A
        sunSetOrRiseA = sunSetOrRiseA.toLocaleTimeString();
        var ssrI = sunSetOrRiseA.lastIndexOf(":");
        sunSetOrRiseA = sunSetOrRiseA.substr(0,ssrI) + sunSetOrRiseA.substr(ssrI+4);
        sunSetOrRiseB = (sunSetOrRiseB.toLocaleDateString(hass.selectedLanguage || hass.language, { weekday: 'short' }).slice(0,3)) + " " + sunSetOrRiseB.toLocaleTimeString();
        ssrI = sunSetOrRiseB.lastIndexOf(":");
        sunSetOrRiseB = sunSetOrRiseB.substr(0,ssrI) + sunSetOrRiseB.substr(ssrI+4);
    } else {
        // next is sunrise == B
        var ss = sunSetOrRiseA;
        sunSetOrRiseA = sunSetOrRiseB.toLocaleTimeString();
        var ssrI = sunSetOrRiseA.lastIndexOf(":");
        sunSetOrRiseA = sunSetOrRiseA.substr(0,ssrI) + sunSetOrRiseA.substr(ssrI+4);
        sunSetOrRiseB = (ss.toLocaleDateString(hass.selectedLanguage || hass.language, { weekday: 'short' }).slice(0,3)) + " " + ss.toLocaleTimeString();
        ssrI = sunSetOrRiseB.lastIndexOf(":");
        sunSetOrRiseB = sunSetOrRiseB.substr(0,ssrI) + sunSetOrRiseB.substr(ssrI+4);
        sunSetOrRiseIconA = "mdi:weather-sunset-up";
        sunSetOrRiseIconB = "mdi:weather-sunset-down";
    }




    const forecast1 = { date: forecastDate1,
    				   condition: this.config.entity_forecast_icon_1,
    				   temphigh: this.config.entity_forecast_high_temp_1,
    				   templow:  this.config.entity_forecast_low_temp_1,
               pop: this.config.entity_forecast_pop_1, };
    const forecast2 = { date: forecastDate2,
    				   condition: this.config.entity_forecast_icon_2,
    				   temphigh: this.config.entity_forecast_high_temp_2,
    				   templow:  this.config.entity_forecast_low_temp_2,
               pop: this.config.entity_forecast_pop_2, };
    const forecast3 = { date: forecastDate3,
    				   condition: this.config.entity_forecast_icon_3,
    				   temphigh: this.config.entity_forecast_high_temp_3,
    				   templow:  this.config.entity_forecast_low_temp_3,
               pop: this.config.entity_forecast_pop_3, };
    const forecast4 = { date: forecastDate4,
    				   condition: this.config.entity_forecast_icon_4,
    				   temphigh: this.config.entity_forecast_high_temp_4,
    				   templow:  this.config.entity_forecast_low_temp_4,
               pop: this.config.entity_forecast_pop_4, };
    const forecast5 = { date: forecastDate5,
    				   condition: this.config.entity_forecast_icon_5,
    				   temphigh: this.config.entity_forecast_high_temp_5,
    				   templow:  this.config.entity_forecast_low_temp_5,
               pop: this.config.entity_forecast_pop_5, };

    const forecast = [forecast1,forecast2,forecast3,forecast4,forecast5];

    this.content.innerHTML = `
      <div>
        <span class="icon bigger" style="background: none, url(/local/icons/weather_icons/animated/${weatherIcons[currentConditions]}.svg) no-repeat; background-size: contain;">${currentConditions}</span>
        <div class="divtemp">
          <span class="temp">${temperature}<span class="tempc"> ${getUnit('temperature')}</span></span>
          <span class="feelslike">Percepita<span class="feelstemp">${feelstemperature}<span class="feelstempc">${getUnit('temperature')}</span></span></span>
        </div>
      </div>
      <span class="tdaysum">Oggi: ${hass.states[this.config.entity_today_summary].state} <br>Previsione: ${hass.states[this.config.entity_daily_summary].state}</span>
      <span>
        <ul class="variations right">
            <li><span class="ha-icon"><ha-icon icon="mdi:water-percent"></ha-icon></span>${humidity}<span class="unit"> %</span></li>
            <li><span class="ha-icon"><ha-icon icon="mdi:gauge"></ha-icon></span>${pressure}<span class="unit"> ${getUnit('air_pressure')}</span></li>
            <li><span class="ha-icon"><ha-icon icon=${sunSetOrRiseIconB}></ha-icon></span>${sunSetOrRiseB}</li>
        </ul>
        <ul class="variations">
            <li><span class="ha-icon"><ha-icon icon="mdi:weather-windy"></ha-icon></span>${windBearing} ${windSpeed}<span class="unit"> ${getUnit('length')}/h</span></li>
            <li><span class="ha-icon"><ha-icon icon="mdi:eye"></ha-icon></span>${visibility}<span class="unit"> ${getUnit('visibility')}</span></li>
            <li><span class="ha-icon"><ha-icon icon=${sunSetOrRiseIconA}></ha-icon></span>${sunSetOrRiseA}</li>
        </ul>
      </span>
      <div class="forecast clear">
          ${forecast.map(daily => `
              <div class="day">
                  <span class="dayname">${(daily.date).toLocaleDateString(hass.selectedLanguage || hass.language, { weekday: 'short' })}</span>
                  <br><i class="icon" style="background: none, url(/local/icons/weather_icons/animated/${weatherIcons[hass.states[daily.condition].state]}.svg) no-repeat; background-size: contain;"></i>
                  <br><span class="highTemp">${Math.round(hass.states[daily.temphigh].state)}${getUnit('temperature')}</span>
                  <br><span class="lowTemp">${Math.round(hass.states[daily.templow].state)}${getUnit('temperature')}</span>
                  <br><span class="highTemp">${Math.round(hass.states[daily.pop].state)}%</span>
              </div>`).join('')}
      </div>
      <span class="threedaysum">
          ${(forecast[0].date).toLocaleDateString(hass.selectedLanguage || hass.language, { weekday: 'short' })}: ${hass.states[this.config.entity_forecast_sum_1].state}<br>
          ${(forecast[1].date).toLocaleDateString(hass.selectedLanguage || hass.language, { weekday: 'short' })}: ${hass.states[this.config.entity_forecast_sum_2].state}<br>
          ${(forecast[2].date).toLocaleDateString(hass.selectedLanguage || hass.language, { weekday: 'short' })}: ${hass.states[this.config.entity_forecast_sum_3].state}<br>
      </span>
      <br></br>`;
  }

  setConfig(config) {
    if (!config.entity_current_conditions ||
    		!config.entity_humidity ||
    		!config.entity_pressure ||
     		!config.entity_temperature ||
    		!config.entity_visibility ||
    		!config.entity_wind_bearing ||
    		!config.entity_wind_speed) {
      throw new Error('Please define entities');
    }
    this.config = config;
  }

  // @TODO: This requires more intelligent logic
  getCardSize() {
    return 3;
  }
}

customElements.define('dark-sky-weather-card', DarkSkyWeatherCard);

and this is dark-sky-weather-card.css

.clear {
    clear: both;
  }

  .card {
    margin: auto;
    padding-top: 2em;
    padding-bottom: 1em;
    padding-left: 1em;
    padding-right:1em;
    position: relative;
    max-width: 600px;
    /* min-width: 200px; */
  }

  .ha-icon {
    height: 18px;
    margin-right: 5px;
    color: var(--paper-item-icon-color);
  }

  .divtemp {
    position: absolute;
  }

  .temp {
    font-weight: 300;
    font-size: 4em;
    color: var(--primary-text-color);
  }

  .tempc {
    font-weight: 300;
    font-size: .5em;
    vertical-align: super;
    color: var(--primary-text-color);
    position: relative;
    top: -1px;
    left: -5px;
  }

  .feelslike {
    font-weight: 300;
    font-size: 1em;
    position: relative;
    top: -32px;
    left: 5px;
  }

  .feelstemp {
    font-size: 2em;
    font-weight: 300;
    position: relative;
    top: 32px;
    left: -58px;
  }

  .feelstempc {
    font-size: .6em;
    font-weight: 300;
    vertical-align: super;
  }

  .tdaysum {
    display: block;
    font-size: .8em;
    position: relative;
    top: 55px;
  }

  .threedaysum {
    display: block;
    font-size: .8em;
    position: relative;
    text-transform: capitalize;
  }

  .variations {
    display: inline-block;
    font-weight: 300;
    color: var(--primary-text-color);
    list-style: none;
    position: relative;
    margin-left: -2em;
    margin-top: 4em;
    text-transform: capitalize;
  }

  .variations.right {
    position: absolute;
    right: 1em;
    margin-left: 0;
    margin-right: 1em;
    text-transform: capitalize;
  }

  .unit {
    font-size: .8em;
  }

  .forecast {
    width: 100%;
    margin: 0 auto;
    height: 10em;
  }

  .day {
    display: block;
    width: 20%;
    float: left;
    text-align: center;
    color: var(--primary-text-color);
    border-right: .1em solid #d9d9d9;
    line-height: 2;
    box-sizing: border-box;
  }

  .dayname {
    text-transform: uppercase;
  }

  .forecast .day:first-child {
    margin-left: 0;
  }

  .forecast .day:nth-last-child(1) {
    border-right: none;
    margin-right: 0;
  }

  .highTemp {
    font-weight: bold;
  }

  .lowTemp {
    color: var(--secondary-text-color);
  }

  .icon.bigger {
    width: 10em;
    height: 10em;
    margin-top: -3em;
    position: absolute;
    right: -20px;
  }

  .icon {
    width: 50px;
    height: 50px;
    margin-right: 5px;
    display: inline-block;
    vertical-align: middle;
    background-size: contain;
    background-position: center center;
    background-repeat: no-repeat;
    text-indent: -9999px;
  }

  .weather {
    font-weight: 300;
    font-size: 1.5em;
    color: var(--primary-text-color);
    text-align: left;
    position: absolute;
    top: -0.5em;
    left: 6em;
    word-wrap: break-word;
    width: 30%;
  }

The existing style of dayname with uppercase is to make the day names in the table all uppercase, so if you changed it to capitalize you’d only have the first letter capped in that table. I.e. wrong spot than woody is looking for.

And then here you’d be applying capitalize to every word using that style, not just the first word. See woody’s screenshot in the post above this one.

But you’re right that you can just use the css style text-transform: capitalize. You either have to create another style class for the name names in the summary (which I considered doing to emphasize the names). Or apply a style without creating a new class, something like this maybe?

<span style="text-transform:capitalize">${forecast[0].date}:</span> ${hass.states[this.config.entity_forecast_sum_1].state}<br>

Or just grab the day naming code that I posted in my original post because it simplifies all of this day naming stuff.

Hey @kslb and @itajackass
Check out my post here

If you use those files you should get what you’re after (and maybe more!)
Let me know if you need help.

Thank you very much… your solution is working…

HI
@jusdwy: you’re right, I merely wanted to point to the css file to use styles, and did say adapt to your needs…

something else:

Chrome inspector complains about this:

weather-card.js:17 Uncaught TypeError: Cannot read property 'unit_system' of undefined
    at getUnit (weather-card.js:17)
    at HTMLElement.set hass [as hass] (weather-card.js:84)
    at HTMLElement._createCards (2716aa0fbd89b9909457.chunk.js:2198)
    at Object.runMethodEffect [as fn] (app-79696026.js:1071)
    at runEffectsForProperty (app-79696026.js:1071)
    at runEffects (app-79696026.js:1071)
    at HTMLElement._propertiesChanged (app-79696026.js:1071)
    at HTMLElement._flushProperties (app-79696026.js:1436

apparently it expects something else in the line:

   const lengthUnit = hass.config.core.unit_system.length;?

50


and line 84, at getunit:

Didn’t mean to imply that you were wrong. Was just trying to help folks with css the same way you were.

And I’m not getting that error. I have an idea what’s causing it though. Line 84 is asking to getUnit of ‘temperature’, but the function doesn’t have a temperature case. So goes into case default. But that may not exactly be right either since it’s also line 17 (?) const lengthUnit = … that’s throwing the error which isn’t even looking at what’s being passed to the function. Maybe remove the call to it from line 84 (save a copy first), and see if it triggers on the next call to that function too (probably air_pressure in your case).

If it’s triggering on both then it’s an issue with hass.config.core.unit_system.length. Which might mean you didn’t set something properly in HA (your issue) or the HA setting doesn’t account for that call properly (HA issue).

Thanks @jusdwy

I’ve tried your new code

<style text-transform: capitalize>${forecast[0].date}</style>: ${hass.states[this.config.entity_forecast_sum_1].state}<br>

but strangely it does not appear the day name

41

I thought it was the translation stuff, but also removing it and using your line of code it’s the same.

Ya sorry, I actually wrote it wrong and didn’t test it. This is tested.

<span style="text-transform:capitalize">${forecast[0].date}:</span> ${hass.states[this.config.entity_forecast_sum_1].state}<br>

And here’s the relevant code in the JS file to change the day names without all this. Should make everything run more efficiently.

//replace all the forecast stuff with this, changing your day names to what you want.

    function dayName(dayNum) {
        const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        if ( dayNum > 6 ) {
            dayNum -= 7;
        }
        return days[dayNum];
    }
 
    var d = new Date();
    const forecast1 = { date: dayName(d.getDay()+1),
    				   condition: this.config.entity_forecast_icon_1,
    				   temphigh: this.config.entity_forecast_high_temp_1,
    				   templow:  this.config.entity_forecast_low_temp_1, 
               pop: this.config.entity_forecast_pop_1, };
    const forecast2 = { date: dayName(d.getDay()+2),
    				   condition: this.config.entity_forecast_icon_2,
    				   temphigh: this.config.entity_forecast_high_temp_2,
    				   templow:  this.config.entity_forecast_low_temp_2,
               pop: this.config.entity_forecast_pop_2, };
    const forecast3 = { date: dayName(d.getDay()+3),
    				   condition: this.config.entity_forecast_icon_3,
    				   temphigh: this.config.entity_forecast_high_temp_3,
    				   templow:  this.config.entity_forecast_low_temp_3,
               pop: this.config.entity_forecast_pop_3, };
    const forecast4 = { date: dayName(d.getDay()+4),
    				   condition: this.config.entity_forecast_icon_4,
    				   temphigh: this.config.entity_forecast_high_temp_4,
    				   templow:  this.config.entity_forecast_low_temp_4,
               pop: this.config.entity_forecast_pop_4, };
    const forecast5 = { date: dayName(d.getDay()+5),
    				   condition: this.config.entity_forecast_icon_5,
    				   temphigh: this.config.entity_forecast_high_temp_5,
    				   templow:  this.config.entity_forecast_low_temp_5,
               pop: this.config.entity_forecast_pop_5, };

    const forecast = [forecast1,forecast2,forecast3,forecast4,forecast5];

// and then the sunrise/sunset stuff. this version only puts the day name the sunrise/sunset isn't today, and swaps their positions in the table based on what is next. it can all be simplified if you don't want that.
// also the time formatting may not be to your liking
    var sunSetOrRiseA = new Date(hass.states[this.config.entity_sun].attributes.next_setting);
    var sunSetOrRiseIconA = "mdi:weather-sunset-down";
    var sunSetOrRiseB = new Date(hass.states[this.config.entity_sun].attributes.next_rising);
    var sunSetOrRiseIconB = "mdi:weather-sunset-up";
    // A == sunset   B == sunrise
    if ( hass.states[this.config.entity_sun].state == "above_horizon" ) {
        // sun has risen, but hasn't set
        // sunset is today (no date displayed). sunrise is tomorrow (display date)
        // next is sunset == A
        sunSetOrRiseA = sunSetOrRiseA.toLocaleTimeString();
        var ssrI = sunSetOrRiseA.lastIndexOf(":");
        sunSetOrRiseA = sunSetOrRiseA.substr(0,ssrI) + sunSetOrRiseA.substr(ssrI+4);
        sunSetOrRiseB = dayName(sunSetOrRiseB.getDay()) + " " + sunSetOrRiseB.toLocaleTimeString();
        ssrI = sunSetOrRiseB.lastIndexOf(":");
        sunSetOrRiseB = sunSetOrRiseB.substr(0,ssrI) + sunSetOrRiseB.substr(ssrI+4);
    } else {
        // next is sunrise == B
        var ss = new Date(sunSetOrRiseA);
        if ( new Date().getDate() != sunSetOrRiseB.getDate() ) {
            // sun hasn't risen, and it's not same day
            // so display dates for both
            sunSetOrRiseA = dayName(sunSetOrRiseB.getDay()) + " " + sunSetOrRiseB.toLocaleTimeString();
            sunSetOrRiseB = dayName(ss.getDay()) + " " + ss.toLocaleTimeString();
        } else {
            // sun hasn't risen, but it's the same day
            // since rise and set are today, no dates displayed
            sunSetOrRiseA = sunSetOrRiseB.toLocaleTimeString();
            sunSetOrRiseB = ss.toLocaleTimeString();
        }
        var ssrI = sunSetOrRiseA.lastIndexOf(":");
        sunSetOrRiseA = sunSetOrRiseA.substr(0,ssrI) + sunSetOrRiseA.substr(ssrI+4);
        ssrI = sunSetOrRiseB.lastIndexOf(":");
        sunSetOrRiseB = sunSetOrRiseB.substr(0,ssrI) + sunSetOrRiseB.substr(ssrI+4);
        sunSetOrRiseIconA = "mdi:weather-sunset-up";
        sunSetOrRiseIconB = "mdi:weather-sunset-down";     
    }

// and then this section replaces the need for all that hass.language stuff
      <div class="forecast clear">
          ${forecast.map(daily => `
              <div class="day">
                  <span class="dayname">${daily.date}</span>
                  <br><i class="icon" style="background: none, url(/local/icons/weather_icons/animated/${weatherIcons[hass.states[daily.condition].state]}.svg) no-repeat; background-size: contain;"></i>
                  <br><span class="highTemp">${Math.round(hass.states[daily.temphigh].state)}${getUnit('temperature')}</span>
                  <br><span class="lowTemp">${Math.round(hass.states[daily.templow].state)}${getUnit('temperature')}</span>
                  <br><span class="highTemp">${Math.round(hass.states[daily.pop].state)}%</span>
              </div>`).join('')}
      </div>
      <span class="threedaysum">
          ${forecast[0].date}: ${hass.states[this.config.entity_forecast_sum_1].state}<br>
          ${forecast[1].date}: ${hass.states[this.config.entity_forecast_sum_2].state}<br>
          ${forecast[2].date}: ${hass.states[this.config.entity_forecast_sum_3].state}<br>
      </span>  

Thanks @jusdwy

Just used your new code and all is PERFECT!

13

If you want I can reshare the code.

Glad you like it.
I’ve already shared it all in my original post here. BTW, looks like beautiful weather today in Italy! Jealous.

That’s the spot I’m updating as I make changes and fix bugs that I notice.

Question: did you change any of the sunrise/sunset code?

I think I’m going to work on pulling out the day names and the hard coded “feels like” into the ui-lovelace.yaml call for the card, so it’s easier for users to change the language (and not have to change the card so card updating is easier).

Yeah, in Rome seems like late October, not December!!! :wink:

I have used all the code you’ve shared in last post, so also the sunrise/sunset part.

Yes, this would be easier for all.

but how? If I take it out, it doesn’t show the C any longer, which proves btw that it is working correctly…?

Only thing I can think of is this:

homeassistant:
  name: Main
  latitude: !secret latitude
  longitude: !secret longitude
  elevation: !secret elevation
  unit_system: metric
  time_zone: !secret time_zone
  customize: !include_dir_merge_named customize
  customize_glob: !include customize_glob.yaml
  packages: !include_dir_named packages
  whitelist_external_dirs: /config

so unit_system is set to metric. which is one of the 2 options allowed…

or is hass.config.unit_system.length someplace else? Never had anything complain about this before.

ya, i just mean temporarily to test whether the next call to that function also throws the error. if the next does too then it’s for sure an issue with hass.config.unit_system.length. If the error doesn’t get thrown then it’s to do with it choosing the default case.

But, yes since it is showing degrees C then it’s working I guess.

Weird error.

EDIT:
actually I just noticed something
your getUnit function looks like this

    const getUnit = function (measure) {
      const lengthUnit = hass.config.core.unit_system.length;
      switch (measure) {
        case 'air_pressure':
          return lengthUnit === 'km' ? 'hPa' : 'mbar';
        case 'length':
          return lengthUnit;
        case 'precipitation':
          return lengthUnit === 'km' ? 'mm' : 'in';
        default:
          return hass.config.core.unit_system[measure] || '';
      }
    };

Note how both times it has hass.config it has core as the next thing? Mine doesn’t have core

      const lengthUnit = hass.config.unit_system.length;

//and
          return hass.config.unit_system[measure] || '';

Maybe that’ll solve it

ah yess! that’s an old remnant I have been searching but apparently had a blind spot…
No matter if it solves it or not, it should be there…

btw
there’s literally no online JS parser that passes the script, do you have a tester for these files?

wait, don’t know where that quote came from… but my getUnit is

const getUnit = function (measure) {
  const lengthUnit = hass.config.unit_system.length;
  switch (measure) {
    case 'air_pressure':
      return lengthUnit === 'km' ? 'hPa' : 'inHg';
    case 'length':
      return lengthUnit;
    case 'visibility':
      return lengthUnit === 'km' ? 'm' : 'in';
    case 'precipitation':
      return lengthUnit === 'km' ? 'mm' : 'in';
    default:
      return hass.config.unit_system[measure] || '';
  }
};

I’ll test little hunks of the code in online JS parsers, basically to see if what I’m trying to do works. Then I’ll pop the code into the script and modify it accordingly (probably used a variable to simulate the HA variable the script is using)

For the whole script, I just clear my cache, and see what happens. Sometimes I breaks, but that’s why save a copy of the previous working version, or comment stuff in/out as I’m testing. The beauty of lovelace is being able to quickly refresh the page without having to reload HA.

What is the latestest working code? Currently I did not achieve that your code would work…

I ge this error in JS: TypeError: hass.states[this.config.entity_feelstemp] is undefined
I’ve copy and pasted your code.

UPDATE: solved

Are you getting an error? Is it not looking right?
Can’t help without knowing what’s wrong.

My error:

Log Details (ERROR)
Thu Dec 06 2018 12:49:55 GMT+0100 (Central European Standard Time)

http://192.168.3.32:8123/local/custom_ui/dark-sky-weather-card.js?v=4.3:1:1 Uncaught SyntaxError: Identifier ‘DarkSkyWeatherCard’ has already been declared

Log Details (ERROR)
Thu Dec 06 2018 12:50:08 GMT+0100 (Central European Standard Time)

http://192.168.3.32:8123/local/custom_ui/dark-sky-weather-card.js?v=4.3:180:56 Uncaught TypeError: daily.date.toLocaleDateString is not a function

Log Details (ERROR)
Thu Dec 06 2018 12:50:12 GMT+0100 (Central European Standard Time)

http://192.168.3.32:8123/local/custom_ui/dark-sky-weather-card.js?v=4.3:180:56 Uncaught TypeError: daily.date.toLocaleDateString is not a function