Returning nested json value

I’m trying to figure out how to use an http get to pull json data and then use one of the returned values. From what I’ve been able to determine so far you have to do it via a lambda function. My goal is to return a simple decimal number from the following json example.

{
  "queryCost": 1,
  "latitude": 42.0333,
  "longitude": -91.5996,
  "resolvedAddress": "Marion, IA, United States",
  "address": "Marion,IA",
  "timezone": "America/Chicago",
  "tzoffset": -5,
  "days": [
    {
      "datetime": "2021-10-16",
      "sunrise": "07:20:23",
      "sunset": "18:22:43",
      "moonphase": 0.42
    }
  ]
}

The attribute I’m trying to get is “moonphase”.

I found someone else trying something similar ESPhome how to read json from web? - ESPHome - Home Assistant Community (home-assistant.io), however I’ve been unable to duplicate it. I’ve also been reading over the documentation for v5 of arduinojson, but that doesn’t seem to want to work either. Below is what I’ve got so far.

sensor:
  - platform: template
    name: "Moon Coverage"
    id: moon_coverage

time:
  - platform: sntp
    id: sntp_time
    timezone: America/Chicago
    on_time:
      - seconds: 0
        minutes: /1
        then:
          - lambda: |-
              HTTPClient http;
              http.begin("https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Marion%2CIA/today?unitGroup=us&key=redacted&include=days&elements=datetime,moonphase,sunrise,sunset");
              http.GET();
              DynamicJsonBuffer jsonBuffer(31000);
              JsonObject& root = jsonBuffer.parseObject(http.getStream());
              
              double moonphase = root["days"]["moonphase"];
              id(moon_coverage).publish_state(moonphase);

              ESP_LOGD("main", "############## %d", moonphase);

The code is supposed to put the value 0.42 into the moonphase variable, then update the moon_coverage sensor with that value. Also log the value to the console.

However this is the extent of the output:

[09:12:10][D][sensor:121]: 'Moon Coverage': Sending state 0.00000  with 1 decimals of accuracy
[09:12:10][D][main:066]: ############## 0

I’ve hit a brick wall trying to figure this out. if anyone could give me some pointers on getting that json attribute I’d be grateful.

Did you try the REST sensor ? it might work in your case, I have it to extract some statistical datas from a website:

  - platform: rest
    resource: "https://matomo.obfuscated"
    name: Mywebsite Semaine
    value_template: '{{ value_json.value | int }}'
    unit_of_measurement: "Visitors"

I hadn’t seen that one. Where is the the documentation for the rest sensor? I’m can’t find it in the esphome documentation.

Edit: I just realized you were talking about doing it in a home assistant sensor. That might be an option, although if I can avoid it I’d like to do the sensor part of this in esphome.

My fault, just realised when seeing your answer you were talking about ESPHome not HA :laughing: Well you might have more options and flexibility to do it in HA and you have easy access now in ESPHome at all entities existing in HA if needed for local processing :wink:

I might do that in the mean time to get it working. Basically this is a Milton moon in my room mod that syncs up the leds with the actual moon phase outside. I’m building it for my 6 year old, and he’s super excited to get it so I might just try the rest sensor for the time being and work on the esphome sensor after its setup.

Side note: for extraction of sunrise,sunset, moon phase, I think that you can get these more easily from an existing weather sensor built in HA :wink:
Screenshot_20211018_175506
Mine gets it straight from Accuweather that works worldwide (I didn’t put moon as not interested in it :wink: I just filled twon I was interested in and done :sunglasses:

Originally I was using something like this, however it was only returning the name of the phase in string format (ex, first_quarter, full, waxing_gibbous, etc), however accuweather wasn’t one of the apis I looked into at the time. I’ll have to check if they that integration can provide the info I need.

The hardware I’m using has 6 LEDs which doesn’t really work out with the major phases. I figured I just had to find an API that had the decimal value to represent the coverage.

Edit: Looks like the accuweather API can return DailyForecasts.Moon.Age, which is the days since the new moon. It should be doable to calculate the current state of the moon from that. However it doesn’t look like the integration returns lunar data.