705 lines
28 KiB
C#
705 lines
28 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.View;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
using static AuroraPLC.PLCBase;
|
|
|
|
namespace AuroraPLC.Views
|
|
{
|
|
public class BITValue : NotifyPropertyChangedBase
|
|
{
|
|
public string Address { get; set; }
|
|
private string _description;
|
|
public string Description {
|
|
get => _description;
|
|
set {
|
|
if (_description != value) {
|
|
_description = value;
|
|
NotifyPropertyChanged("Description");
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool inPutStatus;
|
|
public bool InPutStatus {
|
|
get { return inPutStatus; }
|
|
set {
|
|
if (inPutStatus != value) {
|
|
inPutStatus = value;
|
|
NotifyPropertyChanged("InPutStatus");
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool outPutStatus;
|
|
public bool OutPutStatus {
|
|
get { return outPutStatus; }
|
|
set {
|
|
if (outPutStatus != value) {
|
|
outPutStatus = value;
|
|
NotifyPropertyChanged("OutPutStatus");
|
|
}
|
|
}
|
|
}
|
|
//public string hexAddress { get; set; }
|
|
public int addrOffset { get; set; }
|
|
private bool _use = true; // DataGridRow의 IsEnable과 Binding되는 property
|
|
public bool Use {
|
|
get { return _use; }
|
|
set { SetProperty(ref _use, value); }
|
|
} // DataGridRow의 IsEnable과 Binding되는 property
|
|
}
|
|
|
|
public class UCPLCBitViewModel : NotifyPropertyChangedBase
|
|
{
|
|
Logger Log = new Logger("PLC Mon. Bit");
|
|
|
|
public ICommand CMD_VisibleChanged { get; }
|
|
public ICommand CMD_CalculateFlatness { get; }
|
|
public ICommand CMD_ChangeValue { get; }
|
|
|
|
// 해당 뷰 enable 상태
|
|
/*
|
|
private bool _isUCViewEnabled = true;
|
|
public bool IsUCViewEnabled { get => _isUCViewEnabled; set => SetProperty(ref _isUCViewEnabled, value); }
|
|
*/
|
|
|
|
public ObservableCollection<BITValue> DigitalInputs { get; set; } = new ObservableCollection<BITValue>();
|
|
public ObservableCollection<BITValue> DigitalOutputs { get; set; } = new ObservableCollection<BITValue>();
|
|
|
|
public ObservableCollection<BITValue> DigitalInputsTest { get; set; } = new ObservableCollection<BITValue>();
|
|
public ObservableCollection<BITValue> DigitalOutputsTest { get; set; } = new ObservableCollection<BITValue>();
|
|
|
|
public ObservableCollection<BITValue> DigitalInputsView {
|
|
get {
|
|
if (!string.IsNullOrEmpty(FilterInputDescription) && FilterInputDescription.Split('|').Any(x => x.Length > 0)) {
|
|
DigitalInputsTest.Clear();
|
|
//DigitalInputs.Where(x => x.Description.ToLower().Contains(FilterInputDescription.ToLower())).ToList().ForEach(z => DigitalInputsTest.Add(z));
|
|
FilterInputDescription.Split('|').Where(token => !string.IsNullOrEmpty(token)).ToList().ForEach(filterDesc => DigitalInputs.Where(x => x.Description.ToLower().Contains(filterDesc.ToLower())).ToList().ForEach(z => DigitalInputsTest.Add(z)));
|
|
return DigitalInputsTest;
|
|
} else if (IsInputShowDescriptionExist) {
|
|
DigitalInputsTest.Clear();
|
|
DigitalInputs.Where(x => x.Description != "").ToList().ForEach(z => DigitalInputsTest.Add(z));
|
|
return DigitalInputsTest;
|
|
} else {
|
|
return DigitalInputs;
|
|
}
|
|
}
|
|
}
|
|
public ObservableCollection<BITValue> DigitalOutputsView {
|
|
get {
|
|
if (!string.IsNullOrEmpty(FilterOutputDescription)) {
|
|
DigitalOutputsTest.Clear();
|
|
//DigitalOutputs.Where(x => x.Description.ToLower().Contains(FilterOutputDescription.ToLower())).ToList().ForEach(z => DigitalOutputsTest.Add(z));
|
|
FilterOutputDescription.Split('|').Where(token => !string.IsNullOrEmpty(token)).ToList().ForEach(filterDesc => DigitalOutputs.Where(x => x.Description.ToLower().Contains(filterDesc.ToLower())).ToList().ForEach(z => DigitalOutputsTest.Add(z)));
|
|
return DigitalOutputsTest;
|
|
} else if (IsOutputShowDescriptionExist && string.IsNullOrEmpty(FilterOutputDescription)) {
|
|
DigitalOutputsTest.Clear();
|
|
DigitalOutputs.Where(x => x.Description != "").ToList().ForEach(z => DigitalOutputsTest.Add(z));
|
|
return DigitalOutputsTest;
|
|
} else {
|
|
return DigitalOutputs;
|
|
}
|
|
}
|
|
}
|
|
|
|
//------------------------
|
|
// For Sim Only
|
|
public bool IsThisInput { get; private set; }
|
|
|
|
private bool _isInputShowDescriptionExist;
|
|
public bool IsInputShowDescriptionExist {
|
|
get { return _isInputShowDescriptionExist; }
|
|
set {
|
|
if (_isInputShowDescriptionExist != value) {
|
|
SetProperty(ref _isInputShowDescriptionExist, value);
|
|
NotifyPropertyChanged("DigitalInputsView");
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool _isOutputShowDescriptionExist;
|
|
public bool IsOutputShowDescriptionExist {
|
|
get { return _isOutputShowDescriptionExist; }
|
|
set {
|
|
if (_isOutputShowDescriptionExist != value) {
|
|
SetProperty(ref _isOutputShowDescriptionExist, value);
|
|
NotifyPropertyChanged("DigitalOutputsView");
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _FilterInputDescription;
|
|
public string FilterInputDescription {
|
|
get { return _FilterInputDescription; }
|
|
set {
|
|
if (_FilterInputDescription != value) {
|
|
SetProperty(ref _FilterInputDescription, value);
|
|
NotifyPropertyChanged("DigitalInputsView");
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _FilterOutputDescription;
|
|
public string FilterOutputDescription {
|
|
get { return _FilterOutputDescription; }
|
|
set {
|
|
if (_FilterOutputDescription != value) {
|
|
SetProperty(ref _FilterOutputDescription, value);
|
|
NotifyPropertyChanged("DigitalOutputsView");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Input/Ouput 공용 Item
|
|
private BITValue selectedBitItem;
|
|
public BITValue SelectedBitItem {
|
|
get {
|
|
return selectedBitItem;
|
|
}
|
|
set {
|
|
selectedBitItem = value;
|
|
}
|
|
}
|
|
|
|
private BITValue selectedInputItem;
|
|
public BITValue SelectedInputItem {
|
|
get {
|
|
return selectedInputItem;
|
|
}
|
|
set {
|
|
// 반대편 datagrid 의 선택을 해제한다.
|
|
selectedOutputItem = null;
|
|
NotifyPropertyChanged("SelectedOutputItem");
|
|
//====================================
|
|
selectedInputItem = value;
|
|
// For Sim mode : Input bit change
|
|
IsThisInput = true;
|
|
selectedBitItem = value;
|
|
NotifyPropertyChanged("SelectedBitAddress");
|
|
}
|
|
}
|
|
|
|
//====================================
|
|
|
|
private BITValue selectedOutputItem;
|
|
public BITValue SelectedOutputItem {
|
|
get {
|
|
return selectedOutputItem;
|
|
}
|
|
set {
|
|
// 반대편 datagrid 의 선택을 해제한다.
|
|
selectedInputItem = null;
|
|
NotifyPropertyChanged("SelectedInputItem");
|
|
//=====================================
|
|
selectedOutputItem = value;
|
|
// For Sim mode : Input bit change
|
|
IsThisInput = false;
|
|
selectedBitItem = value;
|
|
NotifyPropertyChanged("SelectedBitAddress");
|
|
}
|
|
}
|
|
|
|
public string SelectedBitAddress {
|
|
get {
|
|
return SelectedBitItem?.Address;
|
|
}
|
|
}
|
|
|
|
private int selectedInputIndex = 0;
|
|
public int SelectedInputIndex {
|
|
get => selectedInputIndex;
|
|
set {
|
|
if (selectedInputIndex != value) {
|
|
selectedInputIndex = value;
|
|
DigitalInputs = InputMaps[value];
|
|
NotifyPropertyChanged("DigitalInputs");
|
|
}
|
|
}
|
|
}
|
|
|
|
private int selectedOutputIndex = 0;
|
|
public int SelectedOutputIndex {
|
|
get => selectedOutputIndex;
|
|
set {
|
|
if (selectedOutputIndex != value) {
|
|
selectedOutputIndex = value;
|
|
DigitalOutputs = OutputMaps[value];
|
|
NotifyPropertyChanged("DigitalOutputs");
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool isActivated = false;
|
|
public bool IsActivated {
|
|
get => isActivated;
|
|
set {
|
|
if (isActivated != value) {
|
|
isActivated = value;
|
|
NotifyPropertyChanged("IsActivated");
|
|
}
|
|
}
|
|
}
|
|
|
|
public Dictionary<int, ObservableCollection<BITValue>> InputMaps = new Dictionary<int, ObservableCollection<BITValue>>();
|
|
public Dictionary<int, ObservableCollection<BITValue>> OutputMaps = new Dictionary<int, ObservableCollection<BITValue>>();
|
|
|
|
private bool isVisible;
|
|
private eLangType curLanguage;
|
|
|
|
private IDeviceEntry DeviceManager;
|
|
private readonly PLCBase _plc;
|
|
private ePLCDevice _deviceName;
|
|
|
|
private readonly DispatcherTimer MonitorTimer;
|
|
|
|
private bool _changeButtonEnable;
|
|
public bool ChangeButtonEnable {
|
|
get => _changeButtonEnable;
|
|
set => SetProperty(ref _changeButtonEnable, value);
|
|
}
|
|
|
|
public UCPLCBitViewModel(IAuroraEnvironment aurora, string deviceId, ePLCNetType plcNetType, ePLCDevice device = ePLCDevice.B)
|
|
{
|
|
DeviceManager = aurora.DeviceManager;
|
|
|
|
CMD_VisibleChanged = new DelegateCommand(VisibleChanged);
|
|
CMD_ChangeValue = new DelegateCommand(ChangeBitValue);
|
|
_deviceName = device;
|
|
|
|
_plc = DeviceManager[deviceId] as PLCBase;
|
|
|
|
ObservableCollection<BITValue> input = new ObservableCollection<BITValue>();
|
|
ObservableCollection<BITValue> output = new ObservableCollection<BITValue>();
|
|
InputMaps.Add(0, input);
|
|
OutputMaps.Add(0, output);
|
|
|
|
isVisible = false;
|
|
curLanguage = PLCBase.Language;
|
|
|
|
// Config 로부터 Input/Output 메모리 맵 파싱 및 할당
|
|
LoadBitFromConfig();
|
|
|
|
Observable.Merge(
|
|
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_DEVICE_ACTIVATED),
|
|
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_DEVICE_DEACTIVATED))
|
|
.Select(msg => msg.Param as string)
|
|
.Where(x => x == deviceId).ObserveOnDispatcher()
|
|
.Subscribe(x => OnDeviceActiveChanged());
|
|
|
|
// Log In/Out 시점 파악을 위한 이벤트 관측하기 : For Write 권한 제어
|
|
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_PERMISSION_CHANGED)
|
|
.Subscribe(x => UpdateWriteState());
|
|
|
|
// 언어 변경 이벤트 구독
|
|
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_LANGUAGE_CHANGED)
|
|
.Select(msg => msg.Param.ToString().Split('-').First().ToLower())//.Where(lan => lan != _currLanguage)
|
|
.ObserveOnDispatcher().Subscribe(lan => UpdateLanguage(lan));
|
|
|
|
DigitalInputs = InputMaps[0];
|
|
DigitalOutputs = OutputMaps[0];
|
|
|
|
// 타이머
|
|
MonitorTimer = new DispatcherTimer();
|
|
MonitorTimer.Tick += OnMonitoring;
|
|
MonitorTimer.Interval = TimeSpan.FromMilliseconds(250);
|
|
}
|
|
|
|
private void UpdateLanguage(string lan)
|
|
{
|
|
// 예외 조건
|
|
// 언어가 변경되었는데, 모니터링 뷰 화면이 아닌 경우,
|
|
if (isVisible == false) {
|
|
} else { // 모니터링 화면인 경우,
|
|
// 타이머 중단
|
|
MonitorTimer.Stop();
|
|
|
|
switch (lan) {
|
|
case "en": {
|
|
UpdateViewLanguage(eLangType.English);
|
|
|
|
break;
|
|
}
|
|
|
|
case "ko": {
|
|
UpdateViewLanguage(eLangType.Korean);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 타이머 재시작
|
|
MonitorTimer.Start();
|
|
}
|
|
}
|
|
|
|
private void UpdateViewLanguage(eLangType langType)
|
|
{
|
|
int i = 0;
|
|
switch (langType) {
|
|
case eLangType.English: {
|
|
foreach (var ioValue in DigitalInputs) {
|
|
if (_deviceName == ePLCDevice.M) {
|
|
ioValue.Description = _plc.MBitInputs[i].description.Comment_EN;
|
|
} else {
|
|
ioValue.Description = _plc.BitInputs[i].description.Comment_EN;
|
|
}
|
|
++i;
|
|
}
|
|
|
|
i = 0;
|
|
foreach (var ioValue in DigitalOutputs) {
|
|
if (_deviceName == ePLCDevice.M) {
|
|
ioValue.Description = _plc.MBitOutputs[i].description.Comment_EN;
|
|
} else {
|
|
ioValue.Description = _plc.BitOutputs[i].description.Comment_EN;
|
|
}
|
|
++i;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case eLangType.Korean: {
|
|
foreach (var ioValue in DigitalInputs) {
|
|
if (_deviceName == ePLCDevice.M) {
|
|
ioValue.Description = _plc.MBitInputs[i].description.Comment_KR;
|
|
} else {
|
|
ioValue.Description = _plc.BitInputs[i].description.Comment_KR;
|
|
}
|
|
++i;
|
|
}
|
|
|
|
i = 0;
|
|
foreach (var ioValue in DigitalOutputs) {
|
|
if (_deviceName == ePLCDevice.M) {
|
|
ioValue.Description = _plc.MBitOutputs[i].description.Comment_KR;
|
|
} else {
|
|
ioValue.Description = _plc.BitOutputs[i].description.Comment_KR;
|
|
}
|
|
++i;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 뷰모델 및 PLC 언어도 업데이트
|
|
PLCBase.Language = langType;
|
|
curLanguage = langType;
|
|
}
|
|
|
|
|
|
private void UpdateWriteState() // 화면 내에서 사용자 권한이 변경되었을 경우
|
|
{
|
|
/*
|
|
var curPermissionLevel = ApplicationExt.PermissionLevel;
|
|
if (curPermissionLevel > (ushort)Aurora.Api.PermissionLevel.LEVEL3 || IsActivated == false) { // 권한 부족
|
|
ChangeButtonEnable = false;
|
|
} else {
|
|
if (PLC.IsViewEnabled) {
|
|
ChangeButtonEnable = true;
|
|
} else {
|
|
ChangeButtonEnable = false;
|
|
}
|
|
}
|
|
*/
|
|
|
|
// Auto 모드인 경우, 변경 불가
|
|
if (PLCStatic.IsViewEnabled) {
|
|
ChangeButtonEnable = true;
|
|
} else {
|
|
ChangeButtonEnable = false;
|
|
}
|
|
}
|
|
|
|
private void VisibleChanged(object obj) // 화면 전환 시 동작하는 곳
|
|
{
|
|
// Change 버튼에 대한 권한 검사를 수행
|
|
UpdateWriteState();
|
|
|
|
isVisible = (bool)obj;
|
|
if (isVisible) {
|
|
// 뷰모델이 가지고 있는 언어와 현재 Aurora 언어가 다르면, 설명 언어를 변경함
|
|
if (curLanguage != _plc.GetLangTypeFrom(ApplicationExt.CurLang)) {
|
|
UpdateViewLanguage(PLCBase.Language);
|
|
}
|
|
|
|
MonitorTimer.Start();
|
|
} else {
|
|
MonitorTimer.Stop();
|
|
}
|
|
}
|
|
|
|
private void OnDeviceActiveChanged()
|
|
{
|
|
IsActivated = _plc.IsActivated;
|
|
if (IsActivated == false) {
|
|
ChangeButtonEnable = false;
|
|
}
|
|
}
|
|
|
|
private void LoadBitFromConfig()
|
|
{
|
|
if (_deviceName == ePLCDevice.M) {
|
|
// Bit Input
|
|
var startAddress = _plc.MBitInputs.Count != 0 ? _plc.MBitInputs.OrderBy(x => x.address).First().address : 0;
|
|
foreach (var inputB in _plc.MBitInputs) {
|
|
// 주소와 설명문으로 파싱
|
|
//(var address, var desc) = inputB;
|
|
//(int address, string desc) = inputB;
|
|
var address = inputB.Item1;
|
|
string desc = null;
|
|
switch (curLanguage) {
|
|
case eLangType.English: {
|
|
desc = inputB.Item2.Comment_EN;
|
|
|
|
break;
|
|
}
|
|
case eLangType.Korean: {
|
|
desc = inputB.Item2.Comment_KR;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
desc?.Trim();
|
|
|
|
// list 는 클래스의 주소값을 가지고 있음 : 얕은 복사
|
|
ObservableCollection<BITValue> list = InputMaps[0];
|
|
|
|
// Scriber 는 4자리 주소 중에서 앞자리 2개는 고정으로 구성되어 있었다. Cell Repair 는 B5000 ~ (B51F0 + F) 범위 사용 중 (아마도..)
|
|
// Scriber 의 2자리만 가지지 말고, 4자리 주소값을 유지한다.
|
|
string strAddress = "M" + address.ToString(); // convert to Hex string (4자리)
|
|
var ioValue = new BITValue() {
|
|
Address = strAddress,
|
|
Description = desc,
|
|
// 메모리 주소 4자리를 유지하게 수정한다.
|
|
//hexAddress = strAddress.Substring(3, strAddress.Length-3), // 마지막 2자리만 보존
|
|
//hexAddress = strAddress.Substring(1, strAddress.Length - 1),
|
|
addrOffset = address - startAddress,
|
|
Use = true // 특정 Value를 사용하지 않을 경우 false로 설정 (DataGridRow의 IsEnabled와 연동)
|
|
};
|
|
// 저장
|
|
list.Add(ioValue);
|
|
}
|
|
|
|
// Bit Output
|
|
startAddress = _plc.MBitOutputs.Count != 0 ? _plc.MBitOutputs.OrderBy(x => x.address).First().address : 0;
|
|
foreach (var outB in _plc.MBitOutputs) {
|
|
// 주소와 설명문으로 파싱
|
|
//(var address, var desc) = outB;
|
|
var address = outB.Item1;
|
|
string desc = null;
|
|
switch (curLanguage) {
|
|
case eLangType.English: {
|
|
desc = outB.Item2.Comment_EN;
|
|
|
|
break;
|
|
}
|
|
case eLangType.Korean: {
|
|
desc = outB.Item2.Comment_KR;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
desc?.Trim();
|
|
|
|
// list 는 클래스의 주소값을 가지고 있음
|
|
ObservableCollection<BITValue> list;
|
|
list = OutputMaps[0];
|
|
|
|
string strAddress = "M" + address.ToString(); // convert to Hex string (4자리)
|
|
var ioValue = new BITValue() {
|
|
Address = strAddress,
|
|
Description = desc,
|
|
//hexAddress = strAddress.Substring(1, strAddress.Length - 1),
|
|
addrOffset = address - startAddress,
|
|
Use = true // 특정 Value를 사용하지 않을 경우 false로 설정 (DataGridRow의 IsEnabled와 연동)
|
|
};
|
|
// 저장
|
|
list.Add(ioValue);
|
|
}
|
|
} else {
|
|
// Bit Input
|
|
var startAddress = _plc.BitInputs.Count != 0 ? _plc.BitInputs.OrderBy(x => x.address).First().address : 0;
|
|
foreach (var inputB in _plc.BitInputs) {
|
|
// 주소와 설명문으로 파싱
|
|
//(var address, var desc) = inputB;
|
|
//(int address, string desc) = inputB;
|
|
var address = inputB.Item1;
|
|
string desc = null;
|
|
switch (curLanguage) {
|
|
case eLangType.English: {
|
|
desc = inputB.Item2.Comment_EN;
|
|
|
|
break;
|
|
}
|
|
case eLangType.Korean: {
|
|
desc = inputB.Item2.Comment_KR;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
desc?.Trim();
|
|
|
|
// list 는 클래스의 주소값을 가지고 있음 : 얕은 복사
|
|
ObservableCollection<BITValue> list = InputMaps[0];
|
|
|
|
// Scriber 는 4자리 주소 중에서 앞자리 2개는 고정으로 구성되어 있었다. Cell Repair 는 B5000 ~ (B51F0 + F) 범위 사용 중 (아마도..)
|
|
// Scriber 의 2자리만 가지지 말고, 4자리 주소값을 유지한다.
|
|
string strAddress = "B" + address.ToString("X4"); // convert to Hex string (4자리)
|
|
var ioValue = new BITValue() {
|
|
Address = strAddress,
|
|
Description = desc,
|
|
// 메모리 주소 4자리를 유지하게 수정한다.
|
|
//hexAddress = strAddress.Substring(3, strAddress.Length-3), // 마지막 2자리만 보존
|
|
//hexAddress = strAddress.Substring(1, strAddress.Length - 1),
|
|
addrOffset = address - startAddress,
|
|
Use = true // 특정 Value를 사용하지 않을 경우 false로 설정 (DataGridRow의 IsEnabled와 연동)
|
|
};
|
|
// 저장
|
|
list.Add(ioValue);
|
|
}
|
|
|
|
// Bit Output
|
|
startAddress = _plc.BitOutputs.Count != 0 ? _plc.BitOutputs.OrderBy(x => x.address).First().address : 0;
|
|
foreach (var outB in _plc.BitOutputs) {
|
|
// 주소와 설명문으로 파싱
|
|
//(var address, var desc) = outB;
|
|
var address = outB.Item1;
|
|
string desc = null;
|
|
switch (curLanguage) {
|
|
case eLangType.English: {
|
|
desc = outB.Item2.Comment_EN;
|
|
|
|
break;
|
|
}
|
|
case eLangType.Korean: {
|
|
desc = outB.Item2.Comment_KR;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
desc?.Trim();
|
|
|
|
// list 는 클래스의 주소값을 가지고 있음
|
|
ObservableCollection<BITValue> list;
|
|
list = OutputMaps[0];
|
|
|
|
string strAddress = "B" + address.ToString("X4"); // convert to Hex string (4자리)
|
|
var ioValue = new BITValue() {
|
|
Address = strAddress,
|
|
Description = desc,
|
|
//hexAddress = strAddress.Substring(1, strAddress.Length - 1),
|
|
addrOffset = address - startAddress,
|
|
Use = true // 특정 Value를 사용하지 않을 경우 false로 설정 (DataGridRow의 IsEnabled와 연동)
|
|
};
|
|
// 저장
|
|
list.Add(ioValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnMonitoring(object sender, EventArgs e)
|
|
{
|
|
if (!_plc.IsActivated) {
|
|
return;
|
|
}
|
|
|
|
// 뷰 상태 모니터링 : Auto 모드, Write 불가
|
|
UpdateWriteState();
|
|
|
|
// Read Input Bit Data
|
|
//var i = 0;
|
|
foreach (var ioValue in DigitalInputs) {
|
|
//var memAddress = Int32.Parse(ioValue.hexAddress, System.Globalization.NumberStyles.HexNumber);
|
|
|
|
if (_deviceName == ePLCDevice.M) {
|
|
ioValue.InPutStatus = _plc.ReadBit(ioValue.addrOffset, ePLCDevice.M).data;
|
|
} else {
|
|
ioValue.InPutStatus = _plc.ReadBit(ioValue.addrOffset).data;
|
|
}
|
|
|
|
//ioValue.Use = true;
|
|
#if DEBUG
|
|
// Data check
|
|
//Debug.WriteLine($"Input Bit : index {i}: {ioValue.InPutStatus}");
|
|
//i++;
|
|
#endif
|
|
}
|
|
|
|
// Read Output Bit data
|
|
foreach (var ioValue in DigitalOutputs) {
|
|
//int memAddress = Int32.Parse(ioValue.hexAddress, System.Globalization.NumberStyles.HexNumber);
|
|
if (_deviceName == ePLCDevice.M) {
|
|
ioValue.OutPutStatus = _plc.ReadBit(ioValue.addrOffset, ePLCDevice.M, isInput: false).data;
|
|
} else {
|
|
ioValue.OutPutStatus = _plc.ReadBit(ioValue.addrOffset, isInput: false).data;
|
|
}
|
|
//ioValue.Use = true;
|
|
}
|
|
}
|
|
|
|
private void ChangeBitValue(object obj)
|
|
{
|
|
if (!_plc.IsActivated) {
|
|
return;
|
|
}
|
|
|
|
/*
|
|
// 사용자 권한에 따라서, 아예 해당 버튼을 disable 하는 방식으로 권한 검사를 처리함
|
|
// 방어용으로 이중 처리 (삭제 가능함)
|
|
var curPermissionLevel = ApplicationExt.PermissionLevel;
|
|
if (curPermissionLevel > (ushort)Aurora.Api.PermissionLevel.LEVEL3) { // 권한 부족
|
|
return;
|
|
}
|
|
|
|
// PLC 가 Auto 모드이면 Write 불가
|
|
if (PLC.CheckProcessAutoMode()) {
|
|
return;
|
|
}
|
|
*/
|
|
|
|
// 시뮬레이션 모드인 경우에는 Input & Output 모두 변경이 가능해야 한다.
|
|
// 리얼 모드인 경우는 기존처럼 Output 만 변경이 가능해야 함
|
|
if (SelectedBitItem == null) {
|
|
return;
|
|
}
|
|
|
|
// 비고. 리얼 모드에서는 입력의 수정 불가: 리얼모드 & Input 은 무시한다...
|
|
if (_plc.IsSimul == false && IsThisInput) {
|
|
return;
|
|
}
|
|
|
|
// Hex 메모리 주소문자를 Hex 정수로 변환 ?
|
|
// hexAddress 가 2자리 수밖에 없음. 원본 메모리 주소(4자리)를 가지도록 수정 필요
|
|
//var memAddress = Int32.Parse(SelectedBitItem.hexAddress, System.Globalization.NumberStyles.HexNumber);
|
|
|
|
// 시뮬 모드에서 Input 메모리를 선택한건지 검사한다.
|
|
if (_deviceName == ePLCDevice.M) {
|
|
if (_plc.IsSimul && IsThisInput) { // 시뮬 & 입력부분
|
|
_plc.WriteBit(SelectedBitItem.addrOffset, !SelectedBitItem.InPutStatus, ePLCDevice.M, isOutput: false);
|
|
} else {
|
|
_plc.WriteBit(SelectedBitItem.addrOffset, !SelectedBitItem.OutPutStatus, ePLCDevice.M);
|
|
}
|
|
} else {
|
|
if (_plc.IsSimul && IsThisInput) { // 시뮬 & 입력부분
|
|
_plc.WriteBit(SelectedBitItem.addrOffset, !SelectedBitItem.InPutStatus, isOutput: false);
|
|
} else {
|
|
_plc.WriteBit(SelectedBitItem.addrOffset, !SelectedBitItem.OutPutStatus);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|