-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This resolves #7. I implemented the features as below. - Receive a request to start/stop measurement of a specific channel through `operation/:channel/`. - Receive a request to update exposure time or period of a specific channel through `setting/:channel/`. The detailed logic for WLM control can be found in #7. To test these features, you can mock the `WLM` class. The following code might be helpful. ```python class WLM: def open(self): print('WLM is connected.') def close(self): print('WLM is disconnected.') def start_measurement(self): print('Measurement is stared.') def stop_measurement(self): print('Measurement is stopped') def set_exposure(self, exposure, channel): print(f'Exposure time of channel {channel} is set to {exposure}.') ``` And the example client code is as follows. ```python import requests BASE_URL = 'http://localhost:8000' with requests.Session() as session: data = {'username': 'user1', 'password': 'OOOO'} response = session.post(BASE_URL + '/user/signin/', json=data) csrf_token = session.cookies.get('csrftoken') headers = {'X-CSRFToken': csrf_token} data = {'exposure': 1} response = session.post(BASE_URL + '/setting/1/', json=data, headers=headers) data = {'period': 1} response = session.post(BASE_URL + '/setting/1/', json=data, headers=headers) data = {'on': True} response = session.post(BASE_URL + '/operation/1/', json=data, headers=headers) # open WLM connection and start measurement of channel 1 data = {'on': True} response = session.post(BASE_URL + '/operation/2/', json=data, headers=headers) # start measurement of channel 2 data = {'on': False} response = session.post(BASE_URL + '/operation/1/', json=data, headers=headers) # stop measurement of channel 1 data = {'on': False} response = session.post(BASE_URL + '/operation/2/', json=data, headers=headers) # stop measurement of channel 2 and close WLM connection response = session.post(BASE_URL + '/user/signout/', headers=headers) print(response.status_code) # 200 ``` P.S. I updated `.pylintrc` file to allow more similar codes like `iquip`.
- Loading branch information
Showing
7 changed files
with
122 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.urls import path | ||
|
||
from . import views | ||
|
||
urlpatterns = [ | ||
path('<int:ch>/', views.handle_info, name='handle channel operation'), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from django.http import HttpResponse | ||
from django.contrib.auth.decorators import login_required | ||
from django.conf import settings | ||
from rest_framework.decorators import api_view | ||
|
||
from operation.models import Operation | ||
from channel.models import Channel | ||
from task.message import ActionType, MessageInfo, MessageQueue | ||
from task.handler import TaskHandler | ||
|
||
def get_running_status(ch: int) -> tuple[bool, bool]: | ||
"""Gets running status of WLM and the given channel. | ||
Args: | ||
ch: Target channel. | ||
Returns: | ||
Tuple with WLM running status and target channel running | ||
""" | ||
latest_operations = ( | ||
Operation.objects.order_by('channel', 'user', '-occurred_at').distinct('channel', 'user') | ||
) # latest operations for each channel and user | ||
is_wlm_running = any(op.on for op in latest_operations) | ||
is_channel_running = any(op.channel.channel == ch and op.on for op in latest_operations) | ||
return is_wlm_running, is_channel_running | ||
|
||
|
||
@login_required | ||
@api_view(['POST']) | ||
def handle_info(request, ch: int): | ||
user = request.user | ||
try: | ||
channel = Channel.objects.get(channel=ch) | ||
except Channel.DoesNotExist: | ||
return HttpResponse(status=404) | ||
if not channel.teams.contains(user.team): | ||
return HttpResponse(status=403) | ||
message_queue: MessageQueue = settings.MESSAGE_QUEUE | ||
req_data = request.data.copy() | ||
on = req_data['on'] | ||
operation = Operation(user=user, channel=channel, on=on) | ||
if on: | ||
is_wlm_running, is_channel_running = get_running_status(ch) | ||
if not is_wlm_running: | ||
task_handler = TaskHandler() | ||
task_handler.start() | ||
if not is_channel_running: | ||
message = MessageInfo(ActionType.OPERATE, ch, {'on': True}) | ||
message_queue.push(message) | ||
operation.save() | ||
else: | ||
operation.save() | ||
is_wlm_running, is_channel_running = get_running_status(ch) | ||
if not is_channel_running: | ||
message = MessageInfo(ActionType.OPERATE, ch, {'on': False}) | ||
message_queue.push(message) | ||
if not is_wlm_running: | ||
message = MessageInfo(ActionType.CLOSE, None, None) | ||
message_queue.push(message) | ||
return HttpResponse(status=200) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.urls import path | ||
|
||
from . import views | ||
|
||
urlpatterns = [ | ||
path('<int:ch>/', views.handle_info, name='handle channel setting'), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from datetime import timedelta | ||
|
||
from django.http import HttpResponse | ||
from django.contrib.auth.decorators import login_required | ||
from django.conf import settings | ||
from rest_framework.decorators import api_view | ||
|
||
from setting.models import Setting | ||
from channel.models import Channel | ||
from task.message import ActionType, MessageInfo, MessageQueue | ||
|
||
@login_required | ||
@api_view(['POST']) | ||
def handle_info(request, ch: int): | ||
user = request.user | ||
try: | ||
channel = Channel.objects.get(channel=ch) | ||
except Channel.DoesNotExist: | ||
return HttpResponse(status=404) | ||
if not channel.teams.contains(user.team): | ||
return HttpResponse(status=403) | ||
message_queue: MessageQueue = settings.MESSAGE_QUEUE | ||
latest_setting = Setting.objects.filter(channel__channel=ch).order_by('-created_at').first() | ||
if latest_setting is None: | ||
exposure, period = None, None | ||
else: | ||
exposure, period = latest_setting.exposure, latest_setting.period | ||
req_data = request.data.copy() | ||
if 'exposure' in req_data: | ||
exposure_s = req_data['exposure'] | ||
exposure = timedelta(seconds=exposure_s) | ||
message = MessageInfo(ActionType.EXPOSURE, ch, {'exposure': exposure}) | ||
message_queue.push(message) | ||
if 'period' in req_data: | ||
period_s = req_data['period'] | ||
period = timedelta(seconds=period_s) | ||
message = MessageInfo(ActionType.PERIOD, ch, {'period': period}) | ||
message_queue.push(message) | ||
setting = Setting(channel=channel, exposure=exposure, period=period) | ||
setting.save() | ||
return HttpResponse(status=200) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters