automotive-sdv

automotive-sdv is a skill for Claude Code, Codex from pangzhenying2025/hermes-automotive-skills. It costs 38 tokens per session (36,167 once invoked), scanned A, original, MIT.

Guidance for building connected-vehicle software that links cars with cloud services. It covers telemetry, remote diagnostics, digital vehicle models, over-the-air updates, and in-vehicle app stores.

In plain words
What is it for?
Use it to plan telemetry clients, cloud APIs, remote commands, fleet management, digital twins, and software update delivery for vehicles.
Why use it?
It helps explain the moving parts of vehicle-to-cloud systems and how they communicate. This can reduce uncertainty when designing connected-car platforms and fleet services.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one. Also seen: positional $N argument.

Needs its repository: it runs a file that does not travel with it, so clone the repository first. The line is python tests/validate_physics.py.

Good fit Use it to plan telemetry clients, cloud APIs, remote commands, fleet management, digital twins, and software update delivery for vehicles.

Compare 6 skills from other repositories ↓
Install

Getting it into your agent

It runs from inside its repository, so the clone comes first — what it calls does not travel with the file alone.

Clone the repo
git clone --depth 1 https://github.com/pangzhenying2025/hermes-automotive-skills
agentmods
npx agentmods add skills/pangzhenying2025/hermes-automotive-skills/automotive-sdv

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for automotive-sdv

README.md
[![agentmods](https://agentmods.dev/badge/skills/pangzhenying2025/hermes-automotive-skills/automotive-sdv/github.svg)](https://agentmods.dev/skills/pangzhenying2025/hermes-automotive-skills/automotive-sdv)
Your own site
<a href="https://agentmods.dev/skills/pangzhenying2025/hermes-automotive-skills/automotive-sdv"><img src="https://agentmods.dev/badge/skills/pangzhenying2025/hermes-automotive-skills/automotive-sdv/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for automotive-sdv

Your own site · 80×15
<a href="https://agentmods.dev/skills/pangzhenying2025/hermes-automotive-skills/automotive-sdv"><img src="https://agentmods.dev/badge/skills/pangzhenying2025/hermes-automotive-skills/automotive-sdv.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 38 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 36,167 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 2 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00038 $0.36167
Opus 5 $0.00019 $0.18083
Sonnet 5 $0.00008 $0.07233
Haiku 4.5 $0.00004 $0.03617

Measured 9d ago against content hash d7a4e1a98718, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-12, from the pricing page.

Security

Grade A, and why

automotive-sdv scanned grade A with 2 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Makes network callslowCapability

Not a fault in itself. Listed so you know the mod talks to something, and to what.

curl -L https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-arm64-v1.3.0.tgz | \

Runs shell commandslowCapability

Expected in a hook, worth knowing in a rule or an instructions file.

subprocess.run(cmd, check=True)
skills/automotive-sdv/SKILL.md · 5,356 lines

How it starts

The opening of the file, as written. The whole thing — 5,356 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Automotive Sdv

Cloud Vehicle Integration

Cloud-Vehicle Integration — Connected Vehicle Platforms

Expert knowledge of vehicle-to-cloud connectivity (MQTT, AMQP, HTTP/2), telemetry streaming, remote diagnostics, cloud-based fleet management, and API gateways.

Core Concepts

Communication Protocols

  1. MQTT: Lightweight pub/sub for telemetry (Eclipse Mosquitto, AWS IoT Core)
  2. AMQP: Reliable message queuing (RabbitMQ, Azure Service Bus)
  3. HTTP/2: RESTful APIs with server push
  4. WebSocket: Real-time bidirectional communication
  5. gRPC: High-performance RPC for services

Architecture Patterns

  • Edge Computing: Process data locally before cloud
  • Digital Twin: Virtual representation of vehicle in cloud
  • Command & Control: Remote vehicle operations
  • Fleet Management: Aggregate analytics across vehicles
  • OTA Coordination: Centralized update management

Production-Ready Implementation

1. Vehicle Telemetry Client (Python/MQTT)

#!/usr/bin/env python3
"""
Vehicle telemetry client using MQTT.
Streams vehicle data to cloud platform with offline buffering.
"""

import json
import time
import sqlite3
from dataclasses import dataclass, asdict
from datetime import datetime
from typing import Optional, List
import paho.mqtt.client as mqtt
import can


@dataclass
class TelemetryMessage:
    """Vehicle telemetry data point."""
    vin: str
    timestamp: str
    message_type: str
    data: dict


class VehicleTelemetryClient:
    """
    MQTT-based telemetry client.

    Features:
    - Real-time telemetry streaming
    - Offline buffering with SQLite
    - Automatic reconnection
    - QoS levels for reliability
    - Compression for bandwidth optimization
    """

    def __init__(self, config_path: str = "/etc/vehicle/telemetry-config.json"):
        self.config = self._load_config(config_path)
        self.vin = self._get_vin()
        self.mqtt_client = None
        self.can_bus = None
        self.offline_buffer = OfflineBuffer()
        self.connected = False

    def _load_config(self, path: str) -> dict:
        """Load configuration."""
        with open(path, 'r') as f:
            return json.load(f)

    def _get_vin(self) -> str:
        """Get vehicle VIN."""
        with open('/sys/firmware/devicetree/base/serial-number', 'r') as f:
            return f.read().strip()

    def connect(self):
        """Connect to MQTT broker."""
        self.mqtt_client = mqtt.Client(
            client_id=f"vehicle-{self.vin}",
            clean_session=False,  # Maintain session across reconnects
            protocol=mqtt.MQTTv5
        )

        # Set credentials
        self.mqtt_client.username_pw_set(
            self.config['mqtt_username'],
            self.config['mqtt_password']
        )

        # Configure TLS
        if self.config.get('mqtt_tls', True):
            self.mqtt_client.tls_set(
                ca_certs=self.config['mqtt_ca_cert'],
                certfile=self.config.get('mqtt_client_cert'),
                keyfile=self.config.get('mqtt_client_key')
            )

        # Set callbacks
        self.mqtt_client.on_connect = self._on_connect
        self.mqtt_client.on_disconnect = self._on_disconnect
        self.mqtt_client.on_message = self._on_message
        self.mqtt_client.on_publish = self._on_publish

        # Set last will (notify cloud if vehicle disconnects unexpectedly)
        self.mqtt_client.will_set(
            f"vehicles/{self.vin}/status",
            payload=json.dumps({
                "status": "offline",
                "timestamp": datetime.utcnow().isoformat()
            }),
            qos=1,
            retain=True
        )

        # Connect
        print(f"[Telemetry] Connecting to {self.config['mqtt_broker']}:{self.config['mqtt_port']}")
        self.mqtt_client.connect(
            self.config['mqtt_broker'],
            self.config['mqtt_port'],
            keepalive=60
        )

        # Start network loop in background
        self.mqtt_client.loop_start()

    def _on_connect(self, client, userdata, flags, rc, properties=None):
        """Handle MQTT connection."""
        if rc == 0:
            print("[Telemetry] Connected to MQTT broker")
            self.connected = True

            # Publish online status
            self.mqtt_client.publish(
                f"vehicles/{self.vin}/status",
                payload=json.dumps({
                    "status": "online",
                    "timestamp": datetime.utcnow().isoformat(),
                    "sw_version": self._get_software_version()
                }),
                qos=1,
                retain=True
            )

            # Subscribe to command topics
            self.mqtt_client.subscribe(f"vehicles/{self.vin}/commands/#", qos=1)

            # Send buffered messages
            self._flush_offline_buffer()
        else:
            print(f"[Telemetry] Connection failed: {rc}")
            self.connected = False

    def _on_disconnect(self, client, userdata, rc):
        """Handle MQTT disconnection."""
        print(f"[Telemetry] Disconnected from broker: {rc}")
        self.connected = False

        if rc != 0:
            print("[Telemetry] Unexpected disconnect, will reconnect")

    def _on_message(self, client, userdata, msg):
        """Handle incoming command messages."""
        print(f"[Telemetry] Received command: {msg.topic}")

        try:
            payload = json.loads(msg.payload.decode())
            self._handle_command(msg.topic, payload)
        except Exception as e:
            print(f"[Telemetry] Error processing command: {e}")

    def _on_publish(self, client, userdata, mid):
        """Handle successful publish."""
        # Remove from offline buffer if it was buffered
        pass

    def _handle_command(self, topic: str, payload: dict):
        """Handle remote commands from cloud."""
        command_type = topic.split('/')[-1]

        if command_type == "diagnostics":
            # Trigger diagnostic data collection
            print("[Telemetry] Starting diagnostic data collection")
            self._collect_diagnostics()

        elif command_type == "update":
            # Trigger OTA update check
            print("[Telemetry] Checking for updates")
            # Integration with OTA system

        elif command_type == "lock":
            # Remote lock command
            print("[Telemetry] Remote lock requested")
            self._remote_lock()

        elif command_type == "honk":
            # Remote horn activation
            print("[Telemetry] Remote honk requested")
            self._remote_honk()

    def publish_telemetry(self, message_type: str, data: dict, qos: int = 0):
        """
        Publish telemetry message.

        Args:
            message_type: Type of telemetry (battery, location, speed, etc.)
            data: Telemetry data
            qos: MQTT QoS level (0, 1, or 2)
        """
        msg = TelemetryMessage(
            vin=self.vin,
            timestamp=datetime.utcnow().isoformat(),
            message_type=message_type,
            data=data
        )

        topic = f"vehicles/{self.vin}/telemetry/{message_type}"
        payload = json.dumps(asdict(msg))

        if self.connected:
            result = self.mqtt_client.publish(topic, payload, qos=qos)

            if result.rc == mqtt.MQTT_ERR_SUCCESS:
                print(f"[Telemetry] Published {message_type}")
            else:
                print(f"[Telemetry] Publish failed: {result.rc}")
                # Buffer for later
                self.offline_buffer.store(topic, payload, qos)
        else:
            # Store in offline buffer
            self.offline_buffer.store(topic, payload, qos)
            print(f"[Telemetry] Buffered {message_type} (offline)")

    def _flush_offline_buffer(self):
        """Send buffered messages when connection restored."""
        messages = self.offline_buffer.retrieve_all()
        print(f"[Telemetry] Flushing {len(messages)} buffered messages")

        for msg in messages:
            self.mqtt_client.publish(msg['topic'], msg['payload'], qos=msg['qos'])
            self.offline_buffer.delete(msg['id'])

    def start_can_monitoring(self):
        """Start monitoring CAN bus and streaming telemetry."""
        print("[Telemetry] Starting CAN bus monitoring")

        # Connect to CAN bus
        self.can_bus = can.interface.Bus(channel='can0', bustype='socketcan')

        # Define telemetry intervals
        intervals = {
            'battery': 60,  # Every minute
            'location': 300,  # Every 5 minutes
            'speed': 10,  # Every 10 seconds
            'diagnostics': 3600,  # Every hour
        }

        last_publish = {k: 0 for k in intervals.keys()}

        while True:
            # Read CAN messages
            msg = self.can_bus.recv(timeout=1.0)

            if msg is None:
                continue

            current_time = time.time()

            # Process specific CAN IDs
            if msg.arbitration_id == 0x123:  # Battery telemetry
                if current_time - last_publish['battery'] >= intervals['battery']:
                    battery_data = self._parse_battery_can(msg.data)
                    self.publish_telemetry('battery', battery_data, qos=1)
                    last_publish['battery'] = current_time

            elif msg.arbitration_id == 0x456:  # Speed/location
                if current_time - last_publish['speed'] >= intervals['speed']:
                    speed_data = self._parse_speed_can(msg.data)
                    self.publish_telemetry('speed', speed_data, qos=0)
                    last_publish['speed'] = current_time

            # Periodic location publish
            if current_time - last_publish['location'] >= intervals['location']:
                location_data = self._get_gps_location()
                self.publish_telemetry('location', location_data, qos=1)
                last_publish['location'] = current_time

    def _parse_battery_can(self, data: bytes) -> dict:
        """Parse battery telemetry from CAN message."""
        return {
            'soc': int.from_bytes(data[0:2], 'big') / 100,  # State of charge %
            'voltage': int.from_bytes(data[2:4], 'big') / 10,  # Volts
            'current': int.from_bytes(data[4:6], 'big', signed=True) / 10,  # Amps
            'temperature': int.from_bytes(data[6:8], 'big') / 10 - 40,  # Celsius
        }

    def _parse_speed_can(self, data: bytes) -> dict:
        """Parse speed telemetry from CAN message."""
        return {
            'speed': int.from_bytes(data[0:2], 'big') / 100,  # km/h
            'odometer': int.from_bytes(data[2:6], 'big') / 10,  # km
        }

    def _get_gps_location(self) -> dict:
        """Get GPS location from GNSS receiver."""
        # Read from gpsd or similar
        return {
            'latitude': 37.7749,
            'longitude': -122.4194,
            'altitude': 16.0,
            'heading': 270.0,
            'accuracy': 3.5
        }

    def _get_software_version(self) -> str:
        """Get vehicle software version."""
        with open('/etc/vehicle/version', 'r') as f:
            return f.read().strip()

    def _collect_diagnostics(self):
        """Collect comprehensive diagnostic data."""
        diagnostics = {
            'dtcs': [],  # Diagnostic Trouble Codes
            'ecu_status': {},
            'battery_health': {},
            'sensor_status': {},
        }

        # Publish diagnostic report
        self.publish_telemetry('diagnostics', diagnostics, qos=1)

    def _remote_lock(self):
        """Execute remote lock command."""
        # Send CAN command to lock doors
        pass

    def _remote_honk(self):
        """Execute remote horn activation."""
        # Send CAN command to honk
        pass

    def disconnect(self):
        """Disconnect from MQTT broker."""
        if self.mqtt_client:
            self.mqtt_client.loop_stop()
            self.mqtt_client.disconnect()

        if self.can_bus:
            self.can_bus.shutdown()


class OfflineBuffer:
    """SQLite-based offline message buffer."""

    def __init__(self, db_path: str = "/var/lib/vehicle/telemetry-buffer.db"):
        self.db_path = db_path
        self._init_db()

    def _init_db(self):
        """Initialize SQLite database."""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()

        cursor.execute('''
            CREATE TABLE IF NOT EXISTS buffer (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                topic TEXT NOT NULL,
                payload TEXT NOT NULL,
                qos INTEGER NOT NULL,
                timestamp REAL NOT NULL
            )
        ''')

        conn.commit()
        conn.close()

    def store(self, topic: str, payload: str, qos: int):
        """Store message in buffer."""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()

        cursor.execute(
            'INSERT INTO buffer (topic, payload, qos, timestamp) VALUES (?, ?, ?, ?)',
            (topic, payload, qos, time.time())
        )

        conn.commit()
        conn.close()

    def retrieve_all(self) -> List[dict]:
        """Retrieve all buffered messages."""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()

        cursor.execute('SELECT id, topic, payload, qos FROM buffer ORDER BY timestamp')
        rows = cursor.fetchall()

        conn.close()

        return [
            {'id': row[0], 'topic': row[1], 'payload': row[2], 'qos': row[3]}
            for row in rows
        ]

    def delete(self, msg_id: int):
        """Delete message from buffer."""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()

        cursor.execute('DELETE FROM buffer WHERE id = ?', (msg_id,))

        conn.commit()
        conn.close()


def main():
    """Main telemetry client loop."""
    client = VehicleTelemetryClient()

    try:
        client.connect()
        client.start_can_monitoring()
    except KeyboardInterrupt:
        print("\n[Telemetry] Shutting down")
        client.disconnect()


if __name__ == "__main__":
    main()

Read the full file on GitHub · 5,356 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 9d ago First seen · 5,356 lines · 38 tokens per session scan A d7a4e1a98718

Subscribe to this mod's changes

automotive-sdv is a skill published in the GitHub repository pangzhenying2025/hermes-automotive-skills (5 stars, last pushed 3mo ago), licensed MIT. It adds 38 tokens to every session and 36,167 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 2 findings (makes network calls, runs shell commands). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-03.

Related

Other skills, from other repositories

apify-actor-development

Important: Before you begin, fill in the generatedBy property in the meta section of .actor/actor.json. Replace it with the tool and model you're currently using, such as "Claude Code with Claude Sonnet 4.5". This helps Apify monitor and improve AGENTS.md for specific AI tools and models.

sickn33/agentic-awesome-skills · 71 tokens

dynamo-recipe-runner

Select, validate, patch, and deploy existing NVIDIA Dynamo Kubernetes recipes. Use for model/backend/GPU/deployment-mode recipe bring-up; use router-starter for router-only mode work and troubleshoot for broken deployments.

NVIDIA/skills · 49 tokens

enterprise

Enterprise-grade systems with microservices, Kubernetes, Terraform, and AI Native methodology. For multi-feature initiatives spanning a release timeline, combine with /sprint master-plan (v2.1.13) to group features into a single 8-phase sprint container with shared scope/budget and 4 auto-pause triggers…

ww-w-ai/bkit-claude-code · 106 tokens

gcp-essentials

Use when running a small product on core Google Cloud via the gcloud CLI: a project, Cloud Run deploys, a locked-down Cloud Storage bucket, managed Cloud SQL, and least-privilege IAM wiring them together. NOT AWS (that is aws-essentials), NOT the CI pipeline that ships the image (that is deployment), NOT Postgres…

ericrisco/rsc-harness · 91 tokens

model-deployment

Deploy trained machine learning models as production-ready services using REST APIs, containers, serverless functions, and orchestration platforms. Use when the user requests model deployment or provides relevant inputs for this workflow.

seb1n/awesome-ai-agent-skills · 43 tokens

configure-reverse-proxy

Configure reverse proxy patterns across multiple tools including Nginx, Traefik, and ShinyProxy. Covers WebSocket proxying, path-based and host-based routing, SSL termination, and Docker label auto-discovery. Use when routing multiple services behind a single entry point, proxying WebSocket connections (Shiny…

pjt222/agent-almanac · 98 tokens