Skip to content

Commit

Permalink
Merge branch 'main' into rsdk-7307
Browse files Browse the repository at this point in the history
  • Loading branch information
martha-johnston authored Apr 23, 2024
2 parents 00a99d5 + 69cddd2 commit dd5ecd9
Show file tree
Hide file tree
Showing 22 changed files with 253 additions and 131 deletions.
12 changes: 7 additions & 5 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ on:
jobs:
generate-docs:
if: github.repository_owner == 'viamrobotics'
runs-on: [self-hosted, x64]
container:
image: ghcr.io/viamrobotics/canon:amd64
runs-on: ubuntu-latest
steps:
- name: Checkout Push/Workflow Dispatch
uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install Poetry
uses: snok/install-poetry@v1
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/license_finder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,13 @@ jobs:
license_finder:
if: github.repository_owner == 'viamrobotics'
name: Audit 3rd-Party Licenses
runs-on: [x64, qemu-host]
runs-on: ubuntu-latest
container:
image: ghcr.io/viamrobotics/canon:amd64-cache
options: --platform linux/amd64
timeout-minutes: 30

steps:
- name: Check out code in rdk directory
uses: actions/checkout@v2
with:
fetch-depth: 2
- uses: actions/checkout@v4

- name: Install Poetry
uses: snok/install-poetry@v1
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ on:
jobs:
publish:
if: github.repository_owner == 'viamrobotics'
runs-on: [self-hosted, x64]
container:
image: ghcr.io/viamrobotics/canon:amd64
runs-on: ubuntu-latest

steps:
- name: Download Release
Expand Down
38 changes: 15 additions & 23 deletions .github/workflows/release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,18 @@ on:
jobs:
prepare:
if: github.repository_owner == 'viamrobotics'
runs-on: [self-hosted, x64]
container:
image: ghcr.io/viamrobotics/canon:amd64
runs-on: ubuntu-latest
outputs:
rc_version: ${{ steps.bump_version.outputs.rc_version }}
version: ${{ steps.bump_version.outputs.version }}
steps:
- name: Output Event
run: echo "${{ toJSON(github.event) }}"

- name: Install GH CLI
run: |
type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install Poetry
uses: snok/install-poetry@v1
Expand Down Expand Up @@ -97,9 +88,7 @@ jobs:
build:
needs: prepare
if: github.repository_owner == 'viamrobotics'
runs-on: [self-hosted, x64]
container:
image: ghcr.io/viamrobotics/canon:amd64
runs-on: ubuntu-latest
strategy:
matrix:
include:
Expand All @@ -126,10 +115,15 @@ jobs:
whl: linux_armv7l
steps:
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: rc-${{ needs.prepare.outputs.version }}

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install Poetry
uses: snok/install-poetry@v1

Expand Down Expand Up @@ -158,9 +152,7 @@ jobs:
release:
needs: [prepare, build]
if: github.repository_owner == 'viamrobotics'
runs-on: [self-hosted, x64]
container:
image: ghcr.io/viamrobotics/canon:amd64
runs-on: ubuntu-latest

steps:
- uses: actions/download-artifact@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
whl: linux_armv7l
steps:
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: rc-${{ needs.prepare.outputs.version }}

Expand Down
11 changes: 8 additions & 3 deletions examples/server/v1/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from viam.components.arm import Arm
from viam.components.audio_input import AudioInput
from viam.components.base import Base
from viam.components.board import Board
from viam.components.board import Board, TickStream
from viam.components.camera import Camera
from viam.components.encoder import Encoder
from viam.components.gantry import Gantry
Expand All @@ -31,7 +31,7 @@
from viam.components.sensor import Sensor
from viam.components.servo import Servo
from viam.errors import ResourceNotFoundError
from viam.media import MediaStreamWithIterator
from viam.streams import StreamWithIterator
from viam.media.audio import Audio, AudioStream
from viam.media.video import NamedImage
from viam.operations import run_with_operation
Expand Down Expand Up @@ -155,7 +155,7 @@ async def read() -> AsyncIterator[Audio]:

await asyncio.sleep(self.latency.total_seconds())

return MediaStreamWithIterator(read())
return StreamWithIterator(read())

async def get_properties(self) -> AudioInput.Properties:
return AudioInput.Properties(
Expand Down Expand Up @@ -314,6 +314,11 @@ async def set_power_mode(self, **kwargs):
async def write_analog(self, pin: str, value: int, *, timeout: Optional[float] = None, **kwargs):
raise NotImplementedError()

async def stream_ticks(
self, interrupts: List[Board.DigitalInterrupt], *, timeout: Optional[float] = None, **kwargs
) -> TickStream:
raise NotImplementedError()

async def get_geometries(self, extra: Optional[Dict[str, Any]] = None, **kwargs) -> List[Geometry]:
return GEOMETRIES

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "viam-sdk"
version = "0.17.0"
version = "0.18.0"
description = "Viam Robotics Python SDK"
authors = [ "Naveed <[email protected]>" ]
license = "Apache-2.0"
Expand Down
6 changes: 3 additions & 3 deletions src/viam/components/audio_input/audio_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
from google.protobuf.duration_pb2 import Duration
from typing_extensions import Self

from viam.media import MediaSource
from viam.streams import StreamSource
from viam.media.audio import Audio, AudioStream
from viam.proto.component.audioinput import PropertiesResponse
from viam.resource.types import RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT, Subtype

from ..component_base import ComponentBase


class AudioInput(ComponentBase, MediaSource[Audio]):
class AudioInput(ComponentBase, StreamSource[Audio]):
"""AudioInput represents a component that can capture audio.
This acts as an abstract base class for any drivers representing specific
Expand Down Expand Up @@ -67,7 +67,7 @@ async def stream(self, *, timeout: Optional[float] = None, **kwargs) -> AudioStr
"""Stream audio samples from the audio input of the underlying robot
Returns:
MediaStream[Audio]: The stream of audio chunks
Stream[Audio]: The stream of audio chunks
"""
...

Expand Down
6 changes: 3 additions & 3 deletions src/viam/components/audio_input/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from grpclib.client import Channel

from viam.media import MediaStream, MediaStreamWithIterator
from viam.streams import Stream, StreamWithIterator
from viam.media.audio import Audio
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry
from viam.proto.component.audioinput import (
Expand All @@ -29,7 +29,7 @@ def __init__(self, name: str, channel: Channel):
self.client = AudioInputServiceStub(channel)
super().__init__(name)

async def stream(self, *, timeout: Optional[float] = None, **__) -> MediaStream[Audio]:
async def stream(self, *, timeout: Optional[float] = None, **__) -> Stream[Audio]:
async def read() -> AsyncIterator[Audio]:
async with self.client.Chunks.open(timeout=timeout) as chunks_stream:
await chunks_stream.send_message(
Expand All @@ -50,7 +50,7 @@ async def read() -> AsyncIterator[Audio]:
audio = Audio(info=info, chunk=response.chunk)
yield audio

return MediaStreamWithIterator(read())
return StreamWithIterator(read())

async def get_properties(self, *, timeout: Optional[float] = None, **__) -> AudioInput.Properties:
request = PropertiesRequest(name=self.name)
Expand Down
4 changes: 2 additions & 2 deletions src/viam/components/board/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from viam.resource.registry import Registry, ResourceRegistration
from viam.utils import message_to_struct

from .board import Board
from .board import Board, Tick, TickStream
from .client import BoardClient
from .service import BoardRPCService

__all__ = [
"Board",
"Board"
]


Expand Down
31 changes: 30 additions & 1 deletion src/viam/components/board/board.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
from datetime import timedelta
from typing import Any, Dict, Final, List, Optional

from viam.proto.component.board import PowerMode
from viam.proto.component.board import PowerMode, StreamTicksResponse
from viam.resource.types import RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT, Subtype
from viam.streams import Stream

from ..component_base import ComponentBase

Tick = StreamTicksResponse
TickStream = Stream[Tick]


class Board(ComponentBase):
"""
Expand Down Expand Up @@ -372,3 +376,28 @@ async def write_analog(self, pin: str, value: int, *, timeout: Optional[float] =
value (int): value to write.
"""
...

@abc.abstractmethod
async def stream_ticks(
self, interrupts: List[DigitalInterrupt], *, timeout: Optional[float] = None, **kwargs
) -> TickStream:
"""
Stream digital interrupt ticks.
::
my_board = Board.from_robot(robot=robot, name="my_board")
di8 = await my_board.digital_interrupt_by_name(name="8"))
di11 = await my_board.digital_interrupt_by_name(name="11"))
Stream ticks from pins 8 and 11.
ticks = my_board.stream_ticks([di8, di11])
Args:
interrupts (List[DigitalInterrupt]) : list of digital interrupts to recieve ticks from.
Returns:
TickStream: stream of ticks.
"""
...
36 changes: 34 additions & 2 deletions src/viam/components/board/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
from typing import Any, Dict, List, Mapping, Optional

from google.protobuf.duration_pb2 import Duration
from grpclib.client import Channel
from grpclib.client import Channel, Stream as ClientStream

from viam.logging import getLogger
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry
from viam.proto.component.board import (
BoardServiceStub,
Expand All @@ -22,12 +23,17 @@
SetPowerModeRequest,
SetPWMFrequencyRequest,
SetPWMRequest,
StreamTicksRequest,
StreamTicksResponse,
WriteAnalogRequest,
)
from viam.streams import StreamWithIterator
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict

from . import Board
from .board import Board, TickStream

LOGGER = getLogger(__name__)


class AnalogReaderClient(Board.AnalogReader):
Expand Down Expand Up @@ -224,3 +230,29 @@ async def write_analog(
extra = {}
request = WriteAnalogRequest(name=self.name, pin=pin, value=value, extra=dict_to_struct(extra))
await self.client.WriteAnalog(request, timeout=timeout)

async def stream_ticks(
self,
interrupts: List[Board.DigitalInterrupt],
*,
extra: Optional[Dict[str, Any]] = None,
**__,
) -> TickStream:
if extra is None:
extra = {}
names = []
for di in interrupts:
names.append(di.name)
request = StreamTicksRequest(name=self.name, pin_names=names, extra=dict_to_struct(extra))

async def read():
tick_stream: ClientStream[StreamTicksRequest, StreamTicksResponse]
async with self.client.StreamTicks.open() as tick_stream:
try:
await tick_stream.send_message(request, end=True)
async for tick in tick_stream:
yield tick
except Exception as e:
raise (e)

return StreamWithIterator(read())
25 changes: 23 additions & 2 deletions src/viam/components/board/service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from grpclib.server import Stream
from h2.exceptions import StreamClosedError

from viam.errors import MethodNotImplementedError, ResourceNotFoundError
from viam.errors import ResourceNotFoundError
from viam.logging import getLogger
from viam.proto.common import DoCommandRequest, DoCommandResponse, GetGeometriesRequest, GetGeometriesResponse
from viam.proto.component.board import (
BoardServiceBase,
Expand Down Expand Up @@ -32,6 +34,8 @@

from .board import Board

LOGGER = getLogger(__name__)


class BoardRPCService(BoardServiceBase, ResourceRPCServiceBase[Board]):
"""
Expand Down Expand Up @@ -196,4 +200,21 @@ async def GetGeometries(self, stream: Stream[GetGeometriesRequest, GetGeometries
await stream.send_message(response)

async def StreamTicks(self, stream: Stream[StreamTicksRequest, StreamTicksResponse]) -> None:
raise MethodNotImplementedError("StreamTicks").grpc_error
request = await stream.recv_message()
assert request is not None
name = request.name
board = self.get_resource(name)

dis = []
for name in request.pin_names:
dis.append(await board.digital_interrupt_by_name(name))

tick_stream = await board.stream_ticks(interrupts=dis, metadata=stream.metadata)
async for tick in tick_stream:
try:
await stream.send_message(tick)
except StreamClosedError:
return
except Exception as e:
LOGGER.error(e)
return
Loading

0 comments on commit dd5ecd9

Please sign in to comment.