diff --git a/script/scaffold/__main__.py b/script/scaffold/__main__.py
index 93bcc5aba4172caaca139771a70dfbec0c439611..22cdee8f69e0e5f421fe06f90f037e8739df26f9 100644
--- a/script/scaffold/__main__.py
+++ b/script/scaffold/__main__.py
@@ -4,7 +4,7 @@ from pathlib import Path
 import subprocess
 import sys
 
-from . import gather_info, generate, error
+from . import gather_info, generate, error, docs
 from .const import COMPONENT_DIR
 
 
@@ -65,9 +65,11 @@ def main():
     print()
 
     print("Running tests")
-    print(f"$ pytest tests/components/{info.domain}")
+    print(f"$ pytest -v tests/components/{info.domain}")
     if (
-        subprocess.run(f"pytest tests/components/{info.domain}", shell=True).returncode
+        subprocess.run(
+            f"pytest -v tests/components/{info.domain}", shell=True
+        ).returncode
         != 0
     ):
         return 1
@@ -75,6 +77,8 @@ def main():
 
     print(f"Done!")
 
+    docs.print_relevant_docs(args.template, info)
+
     return 0
 
 
diff --git a/script/scaffold/docs.py b/script/scaffold/docs.py
index 54a182be31bd6370ebba87d554137520d847397e..801b8ebb5fd8b0456d7fbf100cf24af0f134a63d 100644
--- a/script/scaffold/docs.py
+++ b/script/scaffold/docs.py
@@ -18,5 +18,16 @@ https://developers.home-assistant.io/docs/en/creating_integration_file_structure
         print(
             f"""
 The config flow has been added to the {info.domain} integration. Next step is to fill in the blanks for the code marked with TODO.
+"""
+        )
+
+    elif template == "reproduce_state":
+        print(
+            f"""
+Reproduce state code has been added to the {info.domain} integration:
+ - {info.integration_dir / "reproduce_state.py"}
+ - {info.tests_dir / "test_reproduce_state.py"}
+
+Please update the relevant items marked as TODO before submitting a pull request.
 """
         )
diff --git a/script/scaffold/templates/reproduce_state/integration/reproduce_state.py b/script/scaffold/templates/reproduce_state/integration/reproduce_state.py
new file mode 100644
index 0000000000000000000000000000000000000000..3449009818b6ab191e740c936dd1301ed1b8af13
--- /dev/null
+++ b/script/scaffold/templates/reproduce_state/integration/reproduce_state.py
@@ -0,0 +1,78 @@
+"""Reproduce an NEW_NAME state."""
+import asyncio
+import logging
+from typing import Iterable, Optional
+
+from homeassistant.const import (
+    ATTR_ENTITY_ID,
+    STATE_ON,
+    STATE_OFF,
+    SERVICE_TURN_OFF,
+    SERVICE_TURN_ON,
+)
+from homeassistant.core import Context, State
+from homeassistant.helpers.typing import HomeAssistantType
+
+from . import DOMAIN
+
+_LOGGER = logging.getLogger(__name__)
+
+# TODO add valid states here
+VALID_STATES = {STATE_ON, STATE_OFF}
+
+
+async def _async_reproduce_state(
+    hass: HomeAssistantType, state: State, context: Optional[Context] = None
+) -> None:
+    """Reproduce a single state."""
+    cur_state = hass.states.get(state.entity_id)
+
+    if cur_state is None:
+        _LOGGER.warning("Unable to find entity %s", state.entity_id)
+        return
+
+    if state.state not in VALID_STATES:
+        _LOGGER.warning(
+            "Invalid state specified for %s: %s", state.entity_id, state.state
+        )
+        return
+
+    # Return if we are already at the right state.
+    if (
+        cur_state.state == state.state
+        and
+        # TODO this is an example attribute
+        cur_state.attributes.get("color") == state.attributes.get("color")
+    ):
+        return
+
+    service_data = {ATTR_ENTITY_ID: state.entity_id}
+
+    # TODO determine the services to call to achieve desired state
+    if state.state == STATE_ON:
+        service = SERVICE_TURN_ON
+        if "color" in state.attributes:
+            service_data["color"] = state.attributes["color"]
+
+    elif state.state == STATE_OFF:
+        service = SERVICE_TURN_OFF
+
+    await hass.services.async_call(
+        DOMAIN, service, service_data, context=context, blocking=True
+    )
+
+
+async def async_reproduce_states(
+    hass: HomeAssistantType, states: Iterable[State], context: Optional[Context] = None
+) -> None:
+    """Reproduce NEW_NAME states."""
+    # TODO pick one and remove other one
+
+    # Reproduce states in parallel.
+    await asyncio.gather(
+        *(_async_reproduce_state(hass, state, context) for state in states)
+    )
+
+    # Alternative: Reproduce states in sequence
+    # for state in states:
+    #     await _async_reproduce_state(hass, state, context)
diff --git a/script/scaffold/templates/reproduce_state/tests/test_reproduce_state.py b/script/scaffold/templates/reproduce_state/tests/test_reproduce_state.py
new file mode 100644
index 0000000000000000000000000000000000000000..ff15625ad7c4fbed052745060f184dfb1739b36f
--- /dev/null
+++ b/script/scaffold/templates/reproduce_state/tests/test_reproduce_state.py
@@ -0,0 +1,56 @@
+"""Test reproduce state for NEW_NAME."""
+from homeassistant.core import State
+
+from tests.common import async_mock_service
+
+
+async def test_reproducing_states(hass, caplog):
+    """Test reproducing NEW_NAME states."""
+    hass.states.async_set("NEW_DOMAIN.entity_off", "off", {})
+    hass.states.async_set("NEW_DOMAIN.entity_on", "on", {"color": "red"})
+
+    turn_on_calls = async_mock_service(hass, "NEW_DOMAIN", "turn_on")
+    turn_off_calls = async_mock_service(hass, "NEW_DOMAIN", "turn_off")
+
+    # These calls should do nothing as entities already in desired state
+    await hass.helpers.state.async_reproduce_state(
+        [
+            State("NEW_DOMAIN.entity_off", "off"),
+            State("NEW_DOMAIN.entity_on", "on", {"color": "red"}),
+        ],
+        blocking=True,
+    )
+
+    assert len(turn_on_calls) == 0
+    assert len(turn_off_calls) == 0
+
+    # Test invalid state is handled
+    await hass.helpers.state.async_reproduce_state(
+        [State("NEW_DOMAIN.entity_off", "not_supported")], blocking=True
+    )
+
+    assert "not_supported" in caplog.text
+    assert len(turn_on_calls) == 0
+    assert len(turn_off_calls) == 0
+
+    # Make sure correct services are called
+    await hass.helpers.state.async_reproduce_state(
+        [
+            State("NEW_DOMAIN.entity_on", "off"),
+            State("NEW_DOMAIN.entity_off", "on", {"color": "red"}),
+            # Should not raise
+            State("NEW_DOMAIN.non_existing", "on"),
+        ],
+        blocking=True,
+    )
+
+    assert len(turn_on_calls) == 1
+    assert turn_on_calls[0].domain == "NEW_DOMAIN"
+    assert turn_on_calls[0].data == {
+        "entity_id": "NEW_DOMAIN.entity_off",
+        "color": "red",
+    }
+
+    assert len(turn_off_calls) == 1
+    assert turn_off_calls[0].domain == "NEW_DOMAIN"
+    assert turn_off_calls[0].data == {"entity_id": "NEW_DOMAIN.entity_on"}
diff --git a/setup.cfg b/setup.cfg
index 49f738cf969eb79d7f7590261898f51a5050b80d..4c9c892b93fbb48104030fba6b5121891920a2e5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -27,11 +27,13 @@ max-line-length = 88
 # W503: Line break occurred before a binary operator
 # E203: Whitespace before ':'
 # D202 No blank lines allowed after function docstring
+# W504 line break after binary operator
 ignore =
     E501,
     W503,
     E203,
-    D202
+    D202,
+    W504
 
 [isort]
 # https://github.com/timothycrosley/isort