scrobble.life
#hive

Home Assistant Users - View your Hive Witness stats at a glance with this dashboard card

Track Your Hive Witness in Home Assistant: Rank, Votes, Stake, Power Down & Portfolio Value

Home Assistant Hive Stats Card

Home Assistant Hive Stats Card lower portion

If you run a Hive witness and already use Home Assistant at home, you can add a dashboard card that keeps an eye on your witness and your wallet. No custom integrations, no HACS, and no API keys. It uses Home Assistant's built-in REST and template features, Hive's public API nodes, and CoinGecko for prices.


What the card shows

Witness

  • Witness rank (active witnesses only, so disabled witnesses are skipped)
  • Total witness votes received (in MHP)
  • Missed blocks

Stake

  • Your own Hive Power, and your effective HP after delegations
  • HP delegated out and delegated in
  • How many witness votes you've cast

Power down

  • Whether a power down is running
  • Weekly payout and amount remaining
  • Countdown to the next payout

Wallet & portfolio

  • Liquid and savings HIVE and HBD
  • Live HIVE and HBD prices
  • Total portfolio value (liquid HIVE + savings + own HP + HBD; HP delegated to you isn't counted)

Prices are in GBP (£) by default. Changing currency is covered further down.


How it works

There are two parts:

  1. A sensor package (hive.yaml). This calls the Hive API (condenser_api.get_accounts, get_dynamic_global_properties, get_witness_by_account and get_witnesses_by_vote) and CoinGecko, then turns VESTS into HP for you.
  2. A dashboard card. A plain Lovelace card that displays those sensors.

How often it updates:

  • Account data: every 5 minutes
  • Witness data: every 10 minutes
  • Rank: every 15 minutes
  • Prices: every 10 minutes
  • The VESTS → HP ratio: hourly

Step 1: Edit the sensor package

Copy the YAML below. Before saving it anywhere, find and replace YOUR_HIVE_ACCOUNT with your account name: lowercase, without the @. It appears 3 times.

###############################################################################
#  HIVE BLOCKCHAIN PACKAGE for Home Assistant
#
#  >>> FIND & REPLACE every "YOUR_HIVE_ACCOUNT" with your account name
#      (lowercase, no @). It appears 3 times in this file.
#  >>> Fiat currency is GBP. To change, replace "gbp" (3 places) and "£".
#
#  Install: save as /config/packages/hive.yaml and make sure
#  configuration.yaml contains:
#
#    homeassistant:
#      packages: !include_dir_named packages
#
#  Then restart Home Assistant (a YAML reload is not enough for new REST sensors).
###############################################################################

rest:
  # ---------------------------------------------------------------- Account
  - resource: https://api.hive.blog
    method: POST
    headers:
      Content-Type: application/json
    payload: '{"jsonrpc":"2.0","method":"condenser_api.get_accounts","params":[["YOUR_HIVE_ACCOUNT"]],"id":1}'
    scan_interval: 300
    timeout: 20
    sensor:
      - name: Hive Liquid HIVE
        unique_id: hive_liquid_hive
        unit_of_measurement: HIVE
        state_class: measurement
        value_template: "{{ value_json.result[0].balance.split(' ')[0] | float(0) }}"
      - name: Hive Savings HIVE
        unique_id: hive_savings_hive
        unit_of_measurement: HIVE
        state_class: measurement
        value_template: "{{ value_json.result[0].savings_balance.split(' ')[0] | float(0) }}"
      - name: Hive Liquid HBD
        unique_id: hive_liquid_hbd
        unit_of_measurement: HBD
        state_class: measurement
        value_template: "{{ value_json.result[0].hbd_balance.split(' ')[0] | float(0) }}"
      - name: Hive Savings HBD
        unique_id: hive_savings_hbd
        unit_of_measurement: HBD
        state_class: measurement
        value_template: "{{ value_json.result[0].savings_hbd_balance.split(' ')[0] | float(0) }}"
      - name: Hive Vests Own
        unique_id: hive_vests_own
        unit_of_measurement: VESTS
        value_template: "{{ value_json.result[0].vesting_shares.split(' ')[0] | float(0) }}"
      - name: Hive Vests Delegated Out
        unique_id: hive_vests_delegated_out
        unit_of_measurement: VESTS
        value_template: "{{ value_json.result[0].delegated_vesting_shares.split(' ')[0] | float(0) }}"
      - name: Hive Vests Received
        unique_id: hive_vests_received
        unit_of_measurement: VESTS
        value_template: "{{ value_json.result[0].received_vesting_shares.split(' ')[0] | float(0) }}"
      - name: Hive Powerdown Rate Vests
        unique_id: hive_powerdown_rate_vests
        unit_of_measurement: VESTS
        value_template: "{{ value_json.result[0].vesting_withdraw_rate.split(' ')[0] | float(0) }}"
      - name: Hive Powerdown Remaining Vests
        unique_id: hive_powerdown_remaining_vests
        unit_of_measurement: VESTS
        # to_withdraw / withdrawn are raw integers (VESTS x 1,000,000)
        value_template: >
          {% set a = value_json.result[0] %}
          {{ ((a.to_withdraw | int(0)) - (a.withdrawn | int(0))) / 1000000 }}
      - name: Hive Next Powerdown Raw
        unique_id: hive_next_powerdown_raw
        value_template: "{{ value_json.result[0].next_vesting_withdrawal }}"
      - name: Hive Witness Votes Cast
        unique_id: hive_witness_votes_cast
        unit_of_measurement: votes
        value_template: "{{ value_json.result[0].witness_votes | length }}"
      - name: Hive Witness Proxy
        unique_id: hive_witness_proxy
        value_template: "{{ value_json.result[0].proxy if value_json.result[0].proxy else 'none' }}"

  # ------------------------------------------------- Global props (VESTS -> HP)
  - resource: https://api.hive.blog
    method: POST
    headers:
      Content-Type: application/json
    payload: '{"jsonrpc":"2.0","method":"condenser_api.get_dynamic_global_properties","params":[],"id":1}'
    scan_interval: 3600
    timeout: 20
    sensor:
      - name: Hive Per MVests
        unique_id: hive_per_mvests
        unit_of_measurement: HIVE
        value_template: >
          {% set fund = value_json.result.total_vesting_fund_hive.split(' ')[0] | float(0) %}
          {% set shares = value_json.result.total_vesting_shares.split(' ')[0] | float(1) %}
          {{ (fund / shares * 1000000) | round(6) }}

  # ------------------------------------------------------- Witness details
  - resource: https://api.hive.blog
    method: POST
    headers:
      Content-Type: application/json
    payload: '{"jsonrpc":"2.0","method":"condenser_api.get_witness_by_account","params":["YOUR_HIVE_ACCOUNT"],"id":1}'
    scan_interval: 600
    timeout: 20
    sensor:
      - name: Hive Witness Votes Vests
        unique_id: hive_witness_votes_vests
        unit_of_measurement: VESTS
        # "votes" is raw VESTS x 1,000,000
        value_template: "{{ (value_json.result.votes | int(0) / 1000000) if value_json.result else 0 }}"
        json_attributes_path: "$.result"
        json_attributes:
          - total_missed
          - last_confirmed_block_num
          - running_version
          - url
          - signing_key
      - name: Hive Witness Missed Blocks
        unique_id: hive_witness_missed_blocks
        unit_of_measurement: blocks
        value_template: "{{ value_json.result.total_missed if value_json.result else 0 }}"

  # ---------------------------------------- Witness rank (active witnesses only)
  - resource: https://api.hive.blog
    method: POST
    headers:
      Content-Type: application/json
    payload: '{"jsonrpc":"2.0","method":"condenser_api.get_witnesses_by_vote","params":["",300],"id":1}'
    scan_interval: 900
    timeout: 30
    sensor:
      - name: Hive Witness Rank
        unique_id: hive_witness_rank
        # Disabled witnesses (null signing key) are skipped, so the rank matches
        # the "active" rank shown on most Hive witness pages.
        value_template: >
          {% set ns = namespace(i=0, rank=0) %}
          {% for w in value_json.result %}
            {% if w.signing_key != 'STM1111111111111111111111111111111114T1Anm' %}
              {% set ns.i = ns.i + 1 %}
              {% if w.owner == 'YOUR_HIVE_ACCOUNT' %}{% set ns.rank = ns.i %}{% endif %}
            {% endif %}
          {% endfor %}
          {{ ns.rank if ns.rank > 0 else '>' ~ ns.i }}

  # ---------------------------------------------------------------- Prices
  - resource: https://api.coingecko.com/api/v3/simple/price?ids=hive,hive_dollar&vs_currencies=gbp
    scan_interval: 600
    timeout: 20
    sensor:
      - name: Hive Price
        unique_id: hive_price
        unit_of_measurement: "£"
        state_class: measurement
        value_template: "{{ value_json.hive.gbp | float(0) }}"
      - name: HBD Price
        unique_id: hbd_price
        unit_of_measurement: "£"
        state_class: measurement
        value_template: "{{ value_json.hive_dollar.gbp | float(0) }}"

template:
  - sensor:
      - name: Hive Power Own
        unique_id: hive_power_own
        unit_of_measurement: HP
        state_class: measurement
        state: >
          {{ (states('sensor.hive_vests_own') | float(0)
              * states('sensor.hive_per_mvests') | float(0) / 1000000) | round(3) }}

      - name: Hive Power Effective
        unique_id: hive_power_effective
        unit_of_measurement: HP
        state_class: measurement
        state: >
          {% set v = states('sensor.hive_vests_own') | float(0)
                   - states('sensor.hive_vests_delegated_out') | float(0)
                   + states('sensor.hive_vests_received') | float(0) %}
          {{ (v * states('sensor.hive_per_mvests') | float(0) / 1000000) | round(3) }}

      - name: Hive Power Delegated Out
        unique_id: hive_power_delegated_out
        unit_of_measurement: HP
        state: >
          {{ (states('sensor.hive_vests_delegated_out') | float(0)
              * states('sensor.hive_per_mvests') | float(0) / 1000000) | round(3) }}

      - name: Hive Power Received
        unique_id: hive_power_received
        unit_of_measurement: HP
        state: >
          {{ (states('sensor.hive_vests_received') | float(0)
              * states('sensor.hive_per_mvests') | float(0) / 1000000) | round(3) }}

      - name: Hive Powerdown Weekly
        unique_id: hive_powerdown_weekly
        unit_of_measurement: HIVE
        state: >
          {{ (states('sensor.hive_powerdown_rate_vests') | float(0)
              * states('sensor.hive_per_mvests') | float(0) / 1000000) | round(3) }}

      - name: Hive Powerdown Remaining
        unique_id: hive_powerdown_remaining
        unit_of_measurement: HIVE
        state: >
          {{ (states('sensor.hive_powerdown_remaining_vests') | float(0)
              * states('sensor.hive_per_mvests') | float(0) / 1000000) | round(3) }}

      - name: Hive Powerdown Active
        unique_id: hive_powerdown_active
        state: "{{ 'Yes' if states('sensor.hive_powerdown_rate_vests') | float(0) > 0 else 'No' }}"
        icon: mdi:arrow-down-bold-circle-outline

      - name: Hive Next Powerdown
        unique_id: hive_next_powerdown
        device_class: timestamp
        availability: >
          {{ states('sensor.hive_next_powerdown_raw') not in ['unknown', 'unavailable', '']
             and not states('sensor.hive_next_powerdown_raw').startswith('1969') }}
        state: "{{ states('sensor.hive_next_powerdown_raw') ~ '+00:00' }}"

      - name: Hive Witness Votes HP
        unique_id: hive_witness_votes_hp
        unit_of_measurement: HP
        state_class: measurement
        state: >
          {{ (states('sensor.hive_witness_votes_vests') | float(0)
              * states('sensor.hive_per_mvests') | float(0) / 1000000) | round(0) }}

      - name: Hive Witness Votes MHP
        unique_id: hive_witness_votes_mhp
        unit_of_measurement: MHP
        state: "{{ (states('sensor.hive_witness_votes_hp') | float(0) / 1000000) | round(2) }}"

      - name: Hive Portfolio Value
        unique_id: hive_portfolio_value
        unit_of_measurement: "£"
        device_class: monetary
        state: >
          {% set hive = states('sensor.hive_liquid_hive') | float(0)
                      + states('sensor.hive_savings_hive') | float(0)
                      + states('sensor.hive_power_own') | float(0) %}
          {% set hbd = states('sensor.hive_liquid_hbd') | float(0)
                     + states('sensor.hive_savings_hbd') | float(0) %}
          {{ (hive * states('sensor.hive_price') | float(0)
              + hbd * states('sensor.hbd_price') | float(0)) | round(2) }}

Step 2: Add the package to Home Assistant

How you do this depends on how Home Assistant is installed. If Settings has an Add-ons or Apps section, you're on Home Assistant OS: use Option A or B. If you see "Apps require the Home Assistant Operating System", you're on Docker/Container or Core: use Option C.

Option A: Home Assistant OS with the File editor app

  1. Go to Settings → Apps (called Add-ons on older versions) and open the store. Search for File editor, then install and start it. Switch on Show in sidebar.
  2. Open File editor from the sidebar. You'll be in the /config folder.
  3. Click the folder icon (top left), then the new folder icon, and create a folder called packages.
  4. Open packages, click the new file icon and name the file hive.yaml.
  5. Paste in the YAML from Step 1, with your account name in it, and click Save.
  6. Go back to /config and open configuration.yaml (see Step 3).

Option B: Home Assistant OS with the Studio Code Server app

If you'd rather use a VS Code-style editor:

  1. Go to Settings → Apps → store, then install and start Studio Code Server. Switch on Show in sidebar.
  2. Open it from the sidebar. In the file explorer, right-click the root of /config → New Folder → packages.
  3. Right-click packages → New File → hive.yaml. Paste in the YAML and save (Ctrl+S).
  4. Open configuration.yaml from the explorer (see Step 3).

Option C: Docker / Container (or Core) by hand

There are no apps on these installs, so you edit the files directly on the host.

1. Find your config folder. It's the host folder mapped to /config in the container, the one containing configuration.yaml. In docker-compose.yml it's the line that looks like - /some/path:/config. If you're not sure, run this on the host:

docker inspect homeassistant --format '{{ range .Mounts }}{{ .Source }} -> {{ .Destination }}{{ println }}{{ end }}'

The path on the left of -> /config is your folder. Change homeassistant if your container has a different name. On a Core install the folder is usually ~/.homeassistant.

2. Create the package file:

cd /path/to/your/config
mkdir -p packages
nano packages/hive.yaml

Paste in the YAML. To save and exit, press Ctrl+O, Enter, then Ctrl+X.

3. Open configuration.yaml:

nano configuration.yaml

Then follow Step 3 below.

If your config folder is on a NAS or shared over the network, you can also do all of this in a normal desktop text editor.


Step 3: Turn on packages in configuration.yaml

Add these two lines to configuration.yaml:

homeassistant:
  packages: !include_dir_named packages

⚠️ If there's already a homeassistant: line in the file, don't add a second one. Put the packages: line, indented, underneath the existing one.


Step 4: Check and restart

  1. Go to Developer tools → YAML → Check configuration. It should report the configuration as valid.
  2. Do a full restart. A YAML reload won't load new REST sensors.
    • HA OS: Settings → System → ⋮ (top right) → Restart Home Assistant
    • Docker: docker restart homeassistant

Give it a minute or two for the sensors to fill in.


Step 5: Add the dashboard card

  1. Open your dashboard and click the pencil icon (top right) to edit.
  2. Click + Add card, scroll to the bottom and pick Manual.
  3. Delete everything already in the box, paste the YAML below, then click Save.
type: vertical-stack
cards:
  - type: glance
    title: HIVE Witness
    columns: 3
    entities:
      - entity: sensor.hive_witness_rank
        name: Rank
        icon: mdi:podium
      - entity: sensor.hive_witness_votes_mhp
        name: Votes
        icon: mdi:vote
      - entity: sensor.hive_witness_missed_blocks
        name: Missed
        icon: mdi:cube-off-outline

  - type: entities
    entities:
      - type: section
        label: Stake
      - entity: sensor.hive_power_own
        name: Hive Power (own)
        icon: mdi:lightning-bolt
      - entity: sensor.hive_power_effective
        name: Effective HP
        icon: mdi:lightning-bolt-circle
      - entity: sensor.hive_power_delegated_out
        name: Delegated out
        icon: mdi:arrow-right-bold
      - entity: sensor.hive_power_received
        name: Delegated in
        icon: mdi:arrow-left-bold
      - entity: sensor.hive_witness_votes_cast
        name: Witness votes cast
        icon: mdi:account-check

      - type: section
        label: Power Down
      - entity: sensor.hive_powerdown_active
        name: Powering down
      - entity: sensor.hive_powerdown_weekly
        name: Weekly payout
        icon: mdi:calendar-week
      - entity: sensor.hive_powerdown_remaining
        name: Remaining
        icon: mdi:progress-download
      - entity: sensor.hive_next_powerdown
        name: Next payout
        format: relative
        icon: mdi:clock-outline

      - type: section
        label: Wallet
      - entity: sensor.hive_liquid_hive
        name: HIVE (liquid)
        icon: mdi:wallet
      - entity: sensor.hive_savings_hive
        name: HIVE (savings)
        icon: mdi:piggy-bank
      - entity: sensor.hive_liquid_hbd
        name: HBD (liquid)
        icon: mdi:currency-usd
      - entity: sensor.hive_savings_hbd
        name: HBD (savings)
        icon: mdi:piggy-bank-outline
      - entity: sensor.hive_price
        name: HIVE price
        icon: mdi:chart-line
      - entity: sensor.hbd_price
        name: HBD price
        icon: mdi:chart-line-variant

  - type: entity
    entity: sensor.hive_portfolio_value
    name: Portfolio Value
    icon: mdi:cash-multiple

💡 Getting a configuration error? The Manual card starts with some placeholder text, often including a type: line. If you paste underneath it instead of replacing it, you end up with two type: lines and Home Assistant rejects the card. Clear the box completely first. If you still get an error, removing the type: vertical-stack line also fixes it.


Customising

  • Currency: in hive.yaml, replace gbp (3 places) with usd, eur and so on, and £ with your symbol.
  • API node: the package uses api.hive.blog. If that's slow for you, replace each resource: https://api.hive.blog with another node, such as https://api.deathwing.me or https://api.openhive.network. Or run it against your own node, since you're a witness 😉
  • Rank: this counts active witnesses only. If you're outside the top 300, it shows something like >290.
  • Not a witness? The card still works for any account. The witness rows just show 0.

Troubleshooting

  • Sensors show "unavailable": check Settings → System → Logs for errors mentioning rest or hive. The usual cause is a typo in the account name, or YOUR_HIVE_ACCOUNT left in one of the 3 places.
  • Entities not found on the card: if you already had sensors with the same names, Home Assistant may have added _2 to the new ones. Check Settings → Devices & services → Entities, search for "hive" and update the card to match.

Ideas for next steps

  • Add a history graph of witness votes or HIVE price.
  • Create an automation to notify you when your rank changes or missed blocks go up.

Questions and improvements are welcome in the comments 👇

Comments · 6

  • @cryptocoinkb(70)· 6h

    The note that a YAML reload isn’t enough for new REST sensors is the kind of detail that can cause silent failures. I also like the explicit three account-name replacements, though a variable-based package could make account or currency changes less error-prone.

  • @stresskiller(73)· 9h

    and it works like a charm ...

    only improvement i can think of besides the ones you have mentioned is the curent witness version and if it's up to date . There are still a lot of witnesses running the older versions .

  • @engrave(74)· 10h

    Awesome idea :)

  • @stresskiller(73)· 10h

    awesome, will test it in the morning , i still have my home assistant running on a raspberry pi 4 with 8gb .

  • @steevc(81)· 13h

    I used HA some years ago and may try it again as I have various gadgets that it could integrate. This looks neat for those who need it.

  • @hivebuzz(74)· 15h

    Congratulations @c0ff33a! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

    You received more than 94000 HP as payout for your posts, comments and curation.
    Your next payout target is 96000 HP.
    The unit is Hive Power equivalent because post and comment rewards can be split into HP and HBD

    You can view your badges on your board and compare yourself to others in the Ranking If you no longer want to receive notifications, reply to this comment with the word STOP