Skip to content

Commit

Permalink
playing around with the datastructures
Browse files Browse the repository at this point in the history
  • Loading branch information
evalott100 committed Oct 10, 2024
1 parent 07cf0df commit 9ef976c
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 148 deletions.
204 changes: 108 additions & 96 deletions src/fastcs_pandablocks/panda/blocks.py
Original file line number Diff line number Diff line change
@@ -1,142 +1,146 @@
import itertools
from pprint import pprint
from typing import Type
from fastcs_pandablocks.types import EpicsName, ResponseType
from fastcs_pandablocks.types import EpicsName, PandaName, ResponseType

panda_name_to_field = {}

class Field:
def __init__(self, name: EpicsName, field_info: ResponseType):
self.name = name
self.field_info = field_info
def __init__(self, epics_name: EpicsName, panda_name: PandaName, field_info: ResponseType):
self.epics_name = epics_name
self.panda_name = panda_name
self.field_info = field_info
self.value = None
panda_name_to_field[panda_name] = self

def change_value(self, new_field_value):
print("setting value", new_field_value)
self.value = new_field_value
def update_value(self, value):
self.value = value

class TableField(Field):
...
...

class TimeField(Field):
...
...

class BitOutField(Field):
...
...

class PosOutField(Field):
...
...

class ExtOutField(Field):
...
...

class ExtOutBitsField(ExtOutField):
...
...

class BitMuxField(Field):
...
...

class PosMuxField(Field):
...
...

class UintParamField(Field):
...
...

class UintReadField(Field):
...
...

class UintWriteField(Field):
...
...

class IntParamField(Field):
...
...

class IntReadField(Field):
...
...

class IntWriteField(Field):
...
...

class ScalarParamField(Field):
...
...

class ScalarReadField(Field):
...
...

class ScalarWriteField(Field):
...
...

class BitParamField(Field):
...

class BitWriteField(Field):
...
...

class BitReadField(Field):
...
...

class ActionWriteField(Field):
...
class BitWriteField(Field):
...

class ActionReadField(Field):
...
...

class LutParamField(Field):
...
class ActionWriteField(Field):
...

class LutWriteField(Field):
...
class LutParamField(Field):
...

class LutReadField(Field):
...
...

class EnumParamField(Field):
...
class LutWriteField(Field):
...

class EnumWriteField(Field):
...
class EnumParamField(Field):
...

class EnumReadField(Field):
...
...

class TimeSubTypeParamField(Field):
...
class EnumWriteField(Field):
...

class TimeSubTypeReadField(Field):
...
class TimeSubTypeParamField(TimeField):
...

class TimeSubTypeWriteField(Field):
...
class TimeSubTypeReadField(TimeField):
...

class TimeSubTypeWriteField(TimeField):
...

FieldType = (
TableField
| BitParamField
| BitWriteField
| BitReadField
| ActionWriteField
| ActionReadField
| LutParamField
| LutWriteField
| LutReadField
| EnumParamField
| EnumWriteField
| EnumReadField
| TimeSubTypeParamField
| TimeSubTypeReadField
| TimeSubTypeWriteField
| TimeField
| BitOutField
| PosOutField
| ExtOutField
| ExtOutBitsField
| BitMuxField
| PosMuxField
| UintParamField
| UintReadField
| UintWriteField
| IntParamField
| IntReadField
| IntWriteField
| ScalarParamField
| ScalarReadField
| ScalarWriteField
TableField |
TimeField |
BitOutField |
PosOutField |
ExtOutField |
ExtOutBitsField |
BitMuxField |
PosMuxField |
UintParamField |
UintReadField |
UintWriteField |
IntParamField |
IntReadField |
IntWriteField |
ScalarParamField |
ScalarReadField |
ScalarWriteField |
BitParamField |
BitReadField |
BitWriteField |
ActionReadField |
ActionWriteField |
LutParamField |
LutReadField |
LutWriteField |
EnumParamField |
EnumReadField |
EnumWriteField |
TimeSubTypeParamField |
TimeSubTypeReadField |
TimeSubTypeWriteField
)

FIELD_TYPE_TO_FASTCS_TYPE: dict[str, dict[str | None, Type[FieldType]]] = {
Expand Down Expand Up @@ -198,30 +202,38 @@ class TimeSubTypeWriteField(Field):
},
}


class Block:
_sub_blocks: dict[int, dict[EpicsName, FieldType]]

def __init__(self, name: EpicsName, number: int, description: str | None, raw_fields: dict[str, ResponseType]):
self.name = name
_fields: dict[int | None, dict[str, FieldType]]

def __init__(
self,
epics_name: EpicsName,
number: int,
description: str | None,
raw_fields: dict[str, ResponseType]
):
self.epics_name = epics_name
self.number = number
self.description = description
self._sub_blocks = {}
self._fields = {}

for number in range(1, number + 1):
numbered_block = name + EpicsName(str(number))
single_block = self._sub_blocks[number] = {}
numbered_block_name = epics_name + EpicsName(block_number=number)
self._fields[number] = {}

for field_suffix, field_info in (
for field_raw_name, field_info in (
raw_fields.items()
):
field_name = (
numbered_block + EpicsName(field_suffix)
field_epics_name_without_block = field_panda_name.to_epics_name()
print("part", field_epics_name_without_block)
field_epics_name = (
numbered_block_name + field_epics_name_without_block
)
single_block[EpicsName(field_suffix)] = (
FIELD_TYPE_TO_FASTCS_TYPE[field_info.type][field_info.subtype](
field_name, field_info
)
print("WHOE", field_epics_name)
field = FIELD_TYPE_TO_FASTCS_TYPE[field_info.type][field_info.subtype](
field_epics_name, field_panda_name, field_info
)
def change_value(self, new_field_value, block_number, field_name):
self._sub_blocks[block_number][field_name].change_value(new_field_value)
self._fields[number][field_name] = field

def update_value(self, number: int | None, field_name: str, value):
self._fields[number][field_name].update_value(value)
63 changes: 36 additions & 27 deletions src/fastcs_pandablocks/panda/client_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"""

import asyncio
from dataclasses import dataclass
from pprint import pprint
from typing import TypedDict
from pandablocks.asyncio import AsyncioClient
from pandablocks.commands import (
ChangeGroup,
Expand All @@ -18,54 +21,60 @@
Changes,
)

from fastcs_pandablocks.types import ResponseType

from fastcs_pandablocks.types import PandaName, ResponseType

class RawPanda:
_blocks: dict[str, BlockInfo] | None = None
_metadata: tuple[Changes] | None = None

_responses: list[dict[str, ResponseType]] | None = None
_changes: Changes | None = None
blocks: dict[str, BlockInfo] | None = None
fields: list[dict[str, ResponseType]] | None = None
metadata: dict[str, str] | None = None
changes: dict[str, str] | None = None

def __init__(self, host: str):
self._client = AsyncioClient(host)

async def connect(self): await self._client.connect()

async def disconnect(self): await self._client.close()
async def connect(self):
await self._client.connect()
await self.introspect()

async def disconnect(self):
await self._client.close()
self.blocks = None
self.fields = None
self.metadata = None
self.changes = None

async def introspect(self):
self._blocks = await self._client.send(GetBlockInfo())
self._responses = await asyncio.gather(
*[self._client.send(GetFieldInfo(block)) for block in self._blocks],
self.blocks, self.fields, self.metadata, self.changes = {}, [], {}, {}
self.blocks = await self._client.send(GetBlockInfo())
self.fields = await asyncio.gather(
*[self._client.send(GetFieldInfo(block)) for block in self.blocks],
)
self._metadata = await self._client.send(GetChanges(ChangeGroup.ALL, True)),

initial_values = (await self._client.send(GetChanges(ChangeGroup.ALL, True))).values

for field_name, value in initial_values.items():
if field_name.startswith("*METADATA"):
self.metadata[field_name] = value
else:
self.changes[field_name] = value

async def get_changes(self):
self._changes = await self._client.send(GetChanges(ChangeGroup.ALL, False))
if not self.changes:
raise RuntimeError("Panda not introspected.")
self.changes = (await self._client.send(GetChanges(ChangeGroup.ALL, False))).values


async def _sync_with_panda(self):
if not self._client.is_connected():
await self.connect()
await self.introspect()

async def _ensure_connected(self):
if not self._blocks:
await self._sync_with_panda()
if not self.blocks:
await self.connect()

async def __aenter__(self):
await self._sync_with_panda()
await self._ensure_connected()
return self

async def __aexit__(self, exc_type, exc, tb):
await self._ensure_connected()
await self.disconnect()

def __aiter__(self):
return self

async def __anext__(self):
await self._ensure_connected()
return await self.get_changes()
Loading

0 comments on commit 9ef976c

Please sign in to comment.