protected void GetStatusCallback(CallbackArgs callArgs) { acPowerAvailable = callArgs.GetDataFromReadBuffer <bool> (0); if (!acPowerAvailable) { Alarm.Post(powerLossAlarmIndex); } else { Alarm.Clear(powerLossAlarmIndex); } byte stateMask = callArgs.GetDataFromReadBuffer <byte> (1); for (var i = 0; i < channels.Length; ++i) { channels[i].SetValue(Utils.MaskToBoolean(stateMask, i)); } #if INCLUDE_POWER_STRIP_CURRENT var currentMask = callArgs.GetDataFromReadBuffer <byte> (2); for (var i = 0; i < channels.Length; ++i) { if (Utils.MaskToBoolean(currentMask, i)) { ReadOutletCurrentCommunication(i); } } #endif }
public override void OnReceive(uint Type, object Data, ref object Reply) { if (Type == OPCProperty.SendRecClearChannelAlarm) { if (NotifyChannelAlarm.ActiveSubCondition == "NotifyChannelCommError") { NotifyChannelAlarm.Clear(); SetDataModified(true); } } else if (Type == OPCProperty.SendRecRaiseChannelAlarm) { // If not already active subcondition AND uncleared. if ((NotifyChannelAlarm.ActiveSubCondition != "NotifyChannelCommError") && (NotifyChannelAlarm.State != 4) && (NotifyChannelAlarm.State != 2)) { NotifyChannelAlarm.Raise("NotifyChannelCommError", "Notify Error: Redirector is Offline", Severity, true); SetDataModified(true); } } else if (Type == OPCProperty.SendRecLogChannelEventText) { String Message = (String)Data; LogSystemEvent("NotifyChannel", Severity, Message); } else { base.OnReceive(Type, Data, ref Reply); } }
public override void OnReceive(uint Type, object Data, ref object Reply) { // Clear scanner alarm if (Type == OPCProperty.SendRecClearScannerAlarm) { NotifyScannerAlarm.Clear(); SetDataModified(true); } // Set scanner alarm else if (Type == OPCProperty.SendRecRaiseScannerAlarm) { NotifyScannerAlarm.Raise("NotifyCommError", "Error: " + (string)Data, Severity, true); SetDataModified(true); } // Ack alarm else if (Type == OPCProperty.SendRecAckAlarm) { // ToDo Ack SetDataModified(true); } else if (Type == OPCProperty.SendRecLogEventText) { // General debug message raised as event String Message = (String)Data; LogSystemEvent("NotifyScanner", Severity, Message); } else { base.OnReceive(Type, Data, ref Reply); } }
public override void OnReceive(uint Type, object Data, ref object Reply) { if (Type == OPCProperty.SendRecClearChannelAlarm) { if (SparkplugChannelAlarm.ActiveSubCondition == "SparkplugChannelCommError") { SparkplugChannelAlarm.Clear(); SetDataModified(true); } } else if (Type == OPCProperty.SendRecRaiseChannelAlarm) { // If not already active subcondition AND uncleared. if ((SparkplugChannelAlarm.ActiveSubCondition != "SparkplugChannelCommError") && (SparkplugChannelAlarm.State != 4) && (SparkplugChannelAlarm.State != 2)) { SparkplugChannelAlarm.Raise("SparkplugChannelCommError", "SparkplugB Error: Broker is Offline", Severity, true); SetDataModified(true); } } else if (Type == OPCProperty.SendRecRequestConfiguration) { string NodeDeviceId = (string)Data; LogSystemEvent("SparkplugBBroker", Severity, "Request for configuration initiation from: " + NodeDeviceId); SparkplugChannelAlarm.Raise("SparkplugChannelNewDevice", "SparkplugB New Device Connected: " + NodeDeviceId, Severity, true); // Raises an alarm which 'tells' user to check and then request config as a method action on the broker ConfigurePending } else if (Type == OPCProperty.SendRecUpdateConfigQueue) { // Commented the item below out/removed from the above action. All q items are refreshed by driver in one action whenever list changes. // Save the device NodeDeviceId into a list so a user can ask for this to be configured - or rejected? //Array.Resize(ref deviceBuf, deviceBuf.Length + 1); //deviceBuf[deviceBuf.Length - 1] = i.uuid; // Refresh the pending queue ConfigBuf = (string[])Data; } else if (Type == OPCProperty.SendRecReportConfigError) { String Err = (String)Data; SparkplugChannelAlarm.Raise("SparkplugChannelDeviceConfig", "SparkplugB Error configuring device: " + Err, Alarm.AlarmType.Fleeting, Severity, true); } else if (Type == OPCProperty.SendRecLogBrokerEventText) { String Message = (String)Data; LogSystemEvent("SparkplugBBroker", Severity, Message); } else { base.OnReceive(Type, Data, ref Reply); } }
public bool ClearAlarm() { if (state == AutoTopOffState.Error) { if (Alarm.CheckAcknowledged(failAlarmIndex)) { Alarm.Clear(failAlarmIndex); state = AutoTopOffState.Standby; return(true); } } return(false); }
public override void OnReceive(uint Type, object Data, ref object Reply) { if (Type == OPCProperty.SendRecClearChannelAlarm) { if (SELoggerChannelAlarm.ActiveSubCondition == "SELoggerChannelCommError") { SELoggerChannelAlarm.Clear(); SetDataModified(true); } } else if (Type == OPCProperty.SendRecRaiseChannelAlarm) { // If not already active subcondition AND uncleared. if ((SELoggerChannelAlarm.ActiveSubCondition != "SELoggerChannelCommError") && (SELoggerChannelAlarm.State != 4) && (SELoggerChannelAlarm.State != 2)) { SELoggerChannelAlarm.Raise("SELoggerChannelCommError", "SELogger Error: Web API Offline", Severity, true); SetDataModified(true); } } else if (Type == OPCProperty.SendRecRequestConfiguration) { Int32 DeviceId = (Int32)Data; LogSystemEvent("SELoggerChannel", Severity, $"Request for configuration initiation from: {DeviceId}"); SELoggerChannelAlarm.Raise("SELoggerChannelNewDevice", $"SELogger New Device Connected: {DeviceId}", Severity, true); // Raises an alarm which 'tells' user to check and then request config as a method action on the broker ConfigurePending SetDataModified(true); } else if (Type == OPCProperty.SendRecUpdateConfigQueue) { // All q items are refreshed by driver in one action whenever list changes. ConfigBuf = (Int32[])Data; SetDataModified(true); } else if (Type == OPCProperty.SendRecReportConfigError) { String Err = (String)Data; SELoggerChannelAlarm.Raise("SELoggerChannelDeviceConfig", "SELogger Error configuring device: " + Err, Alarm.AlarmType.Fleeting, Severity, true); SetDataModified(true); } else if (Type == OPCProperty.SendRecLogChannelEventText) { String Message = (String)Data; LogSystemEvent("SELoggerConnection", Severity, Message); } else { base.OnReceive(Type, Data, ref Reply); } }
public override void OnValueChangedAction(object parm) { var args = parm as ValueChangedEvent; var oldValue = analogValue; analogValue = ScaleRawLevel(Convert.ToSingle(args.newValue)); if (analogValue < zeroScaleCalibrationActual) { Alarm.Post(sensorDisconnectedAlarmIndex); } else { Alarm.Clear(sensorDisconnectedAlarmIndex); } NotifyValueChanged(name, analogValue, oldValue); }
protected void CalculateWaterLevel() { level = 0; var connectedWaterLevelSensors = 0; foreach (var internalWaterLevelSensor in waterLevelSensors.Values) { if (internalWaterLevelSensor.connected) { level += internalWaterLevelSensor.level; connectedWaterLevelSensors++; } } level /= connectedWaterLevelSensors; if (connectedWaterLevelSensors > 0) { dataLogger.AddEntry(level); } else { dataLogger.AddEntry("probe disconnected"); } if (enableHighAnalogAlarm && (level > highAnalogAlarmSetpoint)) { Alarm.Post(highAnalogAlarmIndex); } else { Alarm.Clear(highAnalogAlarmIndex); } if (enableLowAnalogAlarm && (level < lowAnalogAlarmSetpoint)) { Alarm.Post(lowAnalogAlarmIndex); } else { Alarm.Clear(lowAnalogAlarmIndex); } }
public override void OnValueChangedAction(object parm) { var args = parm as ValueChangedEvent; if (waterLevelSensors.ContainsKey(args.name)) { var waterLevelSensor = (WaterLevelSensor)Sensors.WaterLevelSensors.GetGadget(args.name); waterLevelSensors[waterLevelSensor.name].connected = waterLevelSensor.connected; waterLevelSensors[waterLevelSensor.name].level = Convert.ToSingle(waterLevelSensor.value); CalculateWaterLevel(); } else { if (floatSwitches.Contains(args.name)) { var floatSwitch = (FloatSwitch)Sensors.FloatSwitches.GetGadget(args.name); if (floatSwitch.switchFuntion == SwitchFunction.HighLevel) { if (floatSwitch.activated) { Alarm.Post(highSwitchAlarmIndex); } else { Alarm.Clear(highSwitchAlarmIndex); } } else if (floatSwitch.switchFuntion == SwitchFunction.LowLevel) { if (floatSwitch.activated) { Alarm.Post(lowSwitchAlarmIndex); } else { Alarm.Clear(lowSwitchAlarmIndex); } } } } }
public override void Dispose() { Driver.AnalogInput.RemoveChannel(channel); Alarm.Clear(sensorDisconnectedAlarmIndex); Unsubscribe(); }
public override void OnReceive(uint Type, object Data, ref object Reply) { // Clear scanner alarm if (Type == OPCProperty.SendRecClearScannerAlarm) { SparkplugScannerAlarm.Clear(); SetDataModified(true); } // Set scanner alarm else if (Type == OPCProperty.SendRecRaiseScannerAlarm) { SparkplugScannerAlarm.Raise("SparkplugCommLWT", "SparkplugCommError: Offline Last Will Received", Severity, true); SetDataModified(true); } else if (Type == OPCProperty.SendRecProcessLWT) { Int16 SeqNumber = (Int16)Data; LogSystemEvent("SparkplugBND", Severity, "Received Last Will and Testament. Seq: " + SeqNumber.ToString()); //Sequence numbers LastDeathSeq = SeqNumber; LastDeath = DateTime.UtcNow; // Check sequence is valid - only if this is a node and not a device if (DeviceId == "") { // Check done for both Node and Device. Device birth/death sequences should always be zero, so should not raise an alarm? if (LastDeathSeq != LastBirthSeq) { // Error, raise alarm SparkplugScannerAlarm.Raise("SparkplugCommSeq", "SparkplugCommError: Invalid Birth/Death Sequence", Severity, true); } } //TODO Set quality of node points to stale, but not? child device points to stale? SetDataModified(true); } // Recieve Birth data (configuration) for known device else if (Type == OPCProperty.SendRecProcessBCStatus) { // Data is a byte array of a payload byte[] DataBytes = (byte [])(Data); Payload bc = Payload.Parser.ParseFrom(DataBytes); System.DateTime Timestamp = util.UnixTimeStampMillisToDateTime(bc.Timestamp); LogSystemEvent("SparkplugBND", Severity, "Received Birth Certificate. Time: " + Timestamp.ToString()); // Record birth data LastBirth = Timestamp; LastBirthSeq = (Int16)bc.Seq; // Could use this field to set out of service? if (!ActiveState) { LogSystemEvent("SparkplugBND", Severity, "Device is inactive."); } // Scanner good, Clear alarm SparkplugScannerAlarm.Clear(); SetDataModified(true); // Receive configuration for known device // Flag to assume we write a new config, unless can't bool writeNewConfig; LogSystemEvent("SparkplugBND", Severity, "Received Device Configuration."); // Is the config checksum different? Create a Payload with only the Metrics Payload MetricsOnly = new Payload(); foreach (Payload.Types.Metric m in bc.Metrics) { MetricsOnly.Metrics.Add(m); } string ConfigReceived = Payload2Base64(MetricsOnly); if (ConfigReceived == ConfigText) { LogSystemEvent("SparkplugBND", Severity, "Received configuration is the same as the saved version."); writeNewConfig = false; } else { // New configuration received - process this ! LogSystemEvent("SparkplugBND", Severity, "Received configuration for updating an existing device."); writeNewConfig = true; } if (writeNewConfig) { LogSystemEvent("SparkplugBND", Severity, "Received new configuration - writing to Field Device."); SetConfig(MetricsOnly); // Need to receive configuration LogSystemEvent("SparkplugBND", Severity, "Configuration is requested."); ConfReq = true; } // Pass back the reply status as needing config or not. Reply = writeNewConfig ? "Yes" : "No"; } else if (Type == OPCProperty.SendRecFDProtocolError) { // Error interpreting a JSON message - Log Event (may upgrade to alarm later?) LogSystemEvent("SparkplugBND", Severity, (string)Data); } else if (Type == OPCProperty.SendRecLogFDEventText) { // General debug message raised as event String Message = (String)Data; LogSystemEvent("SparkplugBND", Severity, Message); } else if (Type == OPCProperty.SendRecClearConfReq) { ConfReq = false; LogSystemEvent("SparkplugBND", Severity, "Clear Configuration Required Flag."); } else { base.OnReceive(Type, Data, ref Reply); } }
// background thread to dequeue any messages and send to slave // waits for response and calls callback if required private static void txRx() { while (enableTxRx) { int count; lock (messageBuffer.SyncRoot) { count = messageBuffer.Count; } if (count > 0) //We've got messages, lets send them { if (count > 8) { Gtk.Application.Invoke((sender, e) => { Logger.AddWarning(string.Format("Message queue count is {0}", count)); }); } #if DEBUG_SERIAL Console.WriteLine(); Console.WriteLine("*****************Start Message*****************"); #endif InternalMessage m; lock (messageBuffer.SyncRoot) { m = (InternalMessage)messageBuffer.Dequeue(); } if (uart.IsOpen) { m.slave.UpdateStatus(AquaPicBusStatus.CommunicationStart, 0); try { for (int i = 0; i < retryCount; ++i) { uart.DiscardOutBuffer(); uart.DiscardInBuffer(); #if DEBUG_SERIAL Console.WriteLine("Sent Message"); foreach (var w in m.writeBuffer) { Console.WriteLine("{0:X}", w); } #endif //Write message stopwatch.Stop(); int framingDelay = 12 - (int)stopwatch.ElapsedMilliseconds; if (framingDelay > 0) { Thread.Sleep(framingDelay); } uart.Write(m.writeBuffer, 0, m.writeBuffer.Length); // wait for response stopwatch.Restart(); // resets stopwatch for response time, getResponse(ref byte[]) stops it lock (receiveBuffer.SyncLock) { receiveBuffer.responseLength = m.responseLength; receiveBuffer.buffer.Clear(); receiveBuffer.waitForResponse = true; } try { getResponse(ref m.readBuffer); } catch (TimeoutException) { m.slave.UpdateStatus(AquaPicBusStatus.Timeout, readTimeout); Gtk.Application.Invoke((sender, e) => { Logger.AddWarning("APB {0} timeout on function number {1}", m.slave.address, m.writeBuffer[1]); }); #if DEBUG_SERIAL Console.WriteLine("<ERROR> APB {0} timeout on function number {1}", m.slave.Address, m.writeBuffer [1]); #endif } if (m.readBuffer.Length >= m.responseLength) // check response { if (checkResponse(ref m.readBuffer)) // response is good { #if DEBUG_SERIAL Console.WriteLine("Received Message in main thread"); Console.WriteLine("Message length is {0}, expected {1}", m.readBuffer.Length, m.responseLength); foreach (var w in m.readBuffer) { Console.WriteLine("{0:X}", w); } #endif if (m.callback != null) { Gtk.Application.Invoke((sender, e) => m.callback(new CallbackArgs(m.readBuffer))); } if (Alarm.CheckAlarming(m.slave.alarmIdx)) { Alarm.Clear(m.slave.alarmIdx); } m.slave.UpdateStatus(AquaPicBusStatus.CommunicationSuccess, (int)stopwatch.ElapsedMilliseconds); break; // exit for loop } else // Crc error { m.slave.UpdateStatus(AquaPicBusStatus.CrcError, readTimeout); Gtk.Application.Invoke((sender, e) => { Logger.AddWarning("APB {0} crc error on function number {1}", m.slave.address, m.writeBuffer[1]); }); #if DEBUG_SERIAL Console.WriteLine("<ERROR> APB {0} crc error on function number {1}", m.slave.Address, m.writeBuffer [1]); #endif } } else // message length error { m.slave.UpdateStatus(AquaPicBusStatus.LengthError, readTimeout); Gtk.Application.Invoke((sender, e) => { Logger.AddWarning("APB {0} response length error on function number {1}", m.slave.address, m.writeBuffer[1]); }); #if DEBUG_SERIAL Console.WriteLine("<ERROR> APB {0} response length error on function number {1}", m.slave.Address, m.writeBuffer [1]); #endif } lock (receiveBuffer.SyncLock) { receiveBuffer.waitForResponse = false; } } //all retry attempts have failed, post alarm if ((m.slave.status == AquaPicBusStatus.CrcError) || (m.slave.status == AquaPicBusStatus.LengthError) || (m.slave.status == AquaPicBusStatus.Timeout)) { Gtk.Application.Invoke((sender, e) => { Alarm.Post(m.slave.alarmIdx); }); } } catch (Exception ex) { // exception error m.slave.UpdateStatus(AquaPicBusStatus.Exception, 1000); Gtk.Application.Invoke((sender, e) => { Logger.AddError(ex.ToString()); Alarm.Post(m.slave.alarmIdx); }); } } else { m.slave.UpdateStatus(AquaPicBusStatus.NotOpen, 0); } #if DEBUG_SERIAL Console.WriteLine("******************End Message******************"); #endif stopwatch.Restart(); } } }