스케쥴 추가 기능 구현
This commit is contained in:
parent
eb3bc33509
commit
32d0ac69c9
|
|
@ -1,5 +1,6 @@
|
||||||
class ModalsController < ApplicationController
|
class ModalsController < ApplicationController
|
||||||
def open
|
def open
|
||||||
|
@schedule = Schedule.new
|
||||||
render partial: "partials/modals_open", locals: { type: params[:type], close_button: params[:close_button] }
|
render partial: "partials/modals_open", locals: { type: params[:type], close_button: params[:close_button] }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,11 @@
|
||||||
class ModbusController < ApplicationController
|
class ModbusController < ApplicationController
|
||||||
def index
|
|
||||||
@schedule = Schedule.all
|
|
||||||
@modbus_running = Modbus::PollingService.running?
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
schedule = Schedule.find_by(id: params[:id])
|
|
||||||
|
|
||||||
if schedule.destroy
|
|
||||||
redirect_to schedule_edit_modbus_index_path, notice: "스케줄이 삭제되었습니다."
|
|
||||||
else
|
|
||||||
redirect_to schedule_edit_modbus_index_path, alert: "스케줄 삭제에 실패했습니다."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def start
|
def start
|
||||||
Modbus::PollingService.start
|
Modbus::PollingService.start
|
||||||
redirect_to modbus_index_path
|
redirect_to schedules_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def stop
|
def stop
|
||||||
Modbus::PollingService.stop
|
Modbus::PollingService.stop
|
||||||
redirect_to modbus_index_path
|
redirect_to schedules_path
|
||||||
end
|
|
||||||
|
|
||||||
def schedule_edit
|
|
||||||
@schedule = Schedule.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def schedule_edit_update
|
|
||||||
error_time = []
|
|
||||||
|
|
||||||
params[:schedule].each do |id, attributes|
|
|
||||||
schedule = Schedule.find_by(id: id)
|
|
||||||
unless schedule.update(
|
|
||||||
hour: attributes[:hour],
|
|
||||||
minute: attributes[:minute],
|
|
||||||
is_active: attributes[:is_active],
|
|
||||||
temperature: attributes[:temperature]
|
|
||||||
)
|
|
||||||
|
|
||||||
error_time << "#{schedule.hour}시 #{schedule.minute}분"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if error_time.any?
|
|
||||||
redirect_to modbus_index_path, alert: "#{error_time.join(', ')}의 온도 업데이트에 실패하였습니다."
|
|
||||||
else
|
|
||||||
redirect_to modbus_index_path, notice: "스케줄이 성공적으로 업데이트되었습니다."
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
class SchedulesController < ApplicationController
|
||||||
|
def index
|
||||||
|
@schedule = Schedule.order(:hour, :minute)
|
||||||
|
@modbus_running = Modbus::PollingService.running?
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@schedule = Schedule.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@schedule = Schedule.new(schedule_params)
|
||||||
|
|
||||||
|
if @schedule.save
|
||||||
|
redirect_to schedule_edit_schedules_path, notice: "스케쥴이 추가 되었습니다."
|
||||||
|
else
|
||||||
|
error_messages = @schedule.errors.full_messages.join(", ")
|
||||||
|
redirect_to schedule_edit_schedules_path, alert: "스케쥴 추가 실패: #{error_messages}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@schedule = Schedule.find_by(id: params[:id])
|
||||||
|
|
||||||
|
if @schedule.destroy
|
||||||
|
redirect_to schedule_edit_schedules_path, notice: "스케줄이 삭제되었습니다."
|
||||||
|
else
|
||||||
|
error_messages = @schedule.errors.full_messages.join(", ")
|
||||||
|
redirect_to schedule_edit_schedules_path, alert: "스케쥴 삭제 실패: #{error_messages}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def schedule_edit
|
||||||
|
@schedule = Schedule.order(:hour, :minute)
|
||||||
|
end
|
||||||
|
|
||||||
|
def schedule_edit_update
|
||||||
|
error_messages = []
|
||||||
|
|
||||||
|
params[:schedule].each do |id, attributes|
|
||||||
|
schedule = Schedule.find_by(id: id)
|
||||||
|
next unless schedule
|
||||||
|
|
||||||
|
unless schedule.update(
|
||||||
|
hour: attributes[:hour],
|
||||||
|
minute: attributes[:minute],
|
||||||
|
is_active: attributes[:is_active],
|
||||||
|
temperature: attributes[:temperature]
|
||||||
|
)
|
||||||
|
|
||||||
|
error_detail = schedule.errors.full_messages.join(", ")
|
||||||
|
time_label = "#{attributes[:hour]}시 #{attributes[:minute]}분"
|
||||||
|
error_messages << "#{time_label} - #{error_detail}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if error_messages.any?
|
||||||
|
redirect_to schedules_path, alert: error_messages.join("<br>")
|
||||||
|
else
|
||||||
|
redirect_to schedules_path, notice: "스케줄이 성공적으로 업데이트되었습니다."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def schedule_params
|
||||||
|
params.require(:schedule).permit(:hour, :minute, :is_active, :temperature)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
module SchedulesHelper
|
||||||
|
end
|
||||||
|
|
@ -45,10 +45,7 @@ export default class extends Controller {
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const modalsFrame = document.querySelector("turbo-frame#modals")
|
const modalsFrame = document.querySelector("turbo-frame#modals")
|
||||||
if (modalsFrame) {
|
|
||||||
modalsFrame.innerHTML = ""
|
modalsFrame.innerHTML = ""
|
||||||
window.location.reload()
|
|
||||||
}
|
|
||||||
}, 300) // 닫힘 애니메이션 시간과 동일하게 300ms 지연 후 모달 제거
|
}, 300) // 닫힘 애니메이션 시간과 동일하게 300ms 지연 후 모달 제거
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
class Schedule < ApplicationRecord
|
class Schedule < ApplicationRecord
|
||||||
validates :hour, presence: true
|
validates :hour, presence: { message: "시간을 입력하세요" }
|
||||||
validates :minute, presence: true
|
validates :minute, presence: { message: "분을 입력하세요" }
|
||||||
validates :temperature,
|
validates :temperature,
|
||||||
presence: true,
|
presence: { message: "온도를 입력하세요" },
|
||||||
numericality: true,
|
numericality: { message: "온도는 숫자여야 합니다" },
|
||||||
format: { with: /\A\d+(\.\d)?\z/ }
|
format: { with: /\A\d+(\.\d)?\z/, message: "온도는 소수점 한 자리까지 입력 가능합니다" }
|
||||||
validates :minute, uniqueness: { scope: :hour }
|
validates :minute, uniqueness: { scope: :hour, message: "같은 시:분의 스케쥴이 이미 존재합니다" }
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,8 @@ module Modbus
|
||||||
begin
|
begin
|
||||||
now = Time.now
|
now = Time.now
|
||||||
current = [ now.hour, now.min ]
|
current = [ now.hour, now.min ]
|
||||||
|
|
||||||
if current != last_logged
|
if current != last_logged
|
||||||
puts "시간 변경 감지됨: #{current.join(':')}"
|
puts "시간 변경 감지됨: #{format('%02d:%02d', current[0], current[1])}"
|
||||||
schedule = Schedule.find_by(hour: current[0], minute: current[1])
|
schedule = Schedule.find_by(hour: current[0], minute: current[1])
|
||||||
apply_schedule(schedule) if schedule
|
apply_schedule(schedule) if schedule
|
||||||
last_logged = current
|
last_logged = current
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@
|
||||||
<div class="w-full h-full">
|
<div class="w-full h-full">
|
||||||
<% if flash[:notice] %>
|
<% if flash[:notice] %>
|
||||||
<div class="m-4 rounded px-4 py-2 bg-accept text-white">
|
<div class="m-4 rounded px-4 py-2 bg-accept text-white">
|
||||||
<%= flash[:notice] %>
|
<%= raw flash[:notice] %>
|
||||||
</div>
|
</div>
|
||||||
<% elsif flash[:alert] %>
|
<% elsif flash[:alert] %>
|
||||||
<div class="m-4 rounded px-4 py-2 bg-danger text-white">
|
<div class="m-4 rounded px-4 py-2 bg-danger text-white">
|
||||||
<%= flash[:alert] %>
|
<%= raw flash[:alert] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
|
|
|
||||||
|
|
@ -1 +1,39 @@
|
||||||
스케쥴 추가
|
<%= form_with model: @schedule, method: :post, data: { turbo: false }, class: 'flex flex-col h-full divide-y divide-border-table-border' do |form| %>
|
||||||
|
<div class="flex-1 p-4">
|
||||||
|
<table class="base-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>시간</th>
|
||||||
|
<th>분</th>
|
||||||
|
<th>사용여부</th>
|
||||||
|
<th>온도</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<%= form.select :hour,
|
||||||
|
options_for_select((0..23).map { |h| [h.to_s.rjust(2, '0'), h] }, @schedule.hour),
|
||||||
|
{},
|
||||||
|
class: "input-style" %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= form.number_field :minute,
|
||||||
|
min: 0, max: 59, step: 1, inputmode: "decimal", class: "input-style" %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= check_box_tag "schedule[is_active]", "1", true %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= form.number_field :temperature,
|
||||||
|
step: "0.1", inputmode: "decimal", class: "input-style" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex p-4">
|
||||||
|
<%= submit_tag "추가", class: "btn bg-primary" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
@ -37,6 +37,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex p-4">
|
<div class="flex p-4">
|
||||||
<%= link_to "수정", "/modbus/schedule_edit", class: "btn bg-default-slate" %>
|
<%= link_to "수정", schedule_edit_schedules_path, class: "btn bg-default-slate" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<%= form_with url: schedule_edit_update_modbus_index_path, method: :post, class: 'flex flex-col h-full divide-y divide-border-table-border' do %>
|
<%= form_with url: schedule_edit_update_schedules_path, method: :post, class: 'flex flex-col h-full divide-y divide-border-table-border' do %>
|
||||||
<div class="flex-1 p-4">
|
<div class="flex-1 p-4">
|
||||||
<table class="base-table">
|
<table class="base-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<td><%= check_box_tag "schedule[#{s.id}][is_active]", "1", s.is_active == true || s.is_active == 1 %></td>
|
<td><%= check_box_tag "schedule[#{s.id}][is_active]", "1", s.is_active == true || s.is_active == 1 %></td>
|
||||||
<td><%= number_field_tag "schedule[#{s.id}][temperature]", s.temperature, step: "0.1", inputmode: "decimal", class: "input-style" %></td>
|
<td><%= number_field_tag "schedule[#{s.id}][temperature]", s.temperature, step: "0.1", inputmode: "decimal", class: "input-style" %></td>
|
||||||
<td>
|
<td>
|
||||||
<%= link_to "삭제", modbus_path(s),
|
<%= link_to "삭제", schedule_path(s),
|
||||||
data: {
|
data: {
|
||||||
turbo_method: :delete,
|
turbo_method: :delete,
|
||||||
turbo_confirm: "정말 삭제하시겠습니까?"
|
turbo_confirm: "정말 삭제하시겠습니까?"
|
||||||
|
|
@ -10,7 +10,15 @@ Rails.application.routes.draw do
|
||||||
# get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
|
# get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
|
||||||
|
|
||||||
# Defines the root path route ("/")
|
# Defines the root path route ("/")
|
||||||
root "modbus#index"
|
|
||||||
|
root "schedules#index"
|
||||||
|
|
||||||
|
resources :schedules do
|
||||||
|
collection do
|
||||||
|
get "schedule_edit"
|
||||||
|
post "schedule_edit_update"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
resources :modbus do
|
resources :modbus do
|
||||||
collection do
|
collection do
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class SchedulesControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
# test "the truth" do
|
||||||
|
# assert true
|
||||||
|
# end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue