/* ================================================================== * MockRfidEventGenerator.java - 30/07/2016 6:09:01 PM * * Copyright 2007-2016 SolarNetwork.net Dev Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * ================================================================== */ package net.solarnetwork.node.hw.rfid.mock; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; import org.springframework.context.MessageSource; import net.solarnetwork.domain.NodeControlInfo; import net.solarnetwork.domain.NodeControlPropertyType; import net.solarnetwork.node.NodeControlProvider; import net.solarnetwork.node.domain.NodeControlInfoDatum; import net.solarnetwork.node.reactor.Instruction; import net.solarnetwork.node.reactor.InstructionHandler; import net.solarnetwork.node.reactor.InstructionStatus.InstructionState; import net.solarnetwork.node.settings.SettingSpecifier; import net.solarnetwork.node.settings.SettingSpecifierProvider; import net.solarnetwork.node.settings.support.BasicTextFieldSettingSpecifier; /** * Mock RFID scanner that exposes a {@link NodeControlProvider} and * {@link InstructionHandler} for issuing RFID "message received" events. * * @author matt * @version 1.0 */ public class MockRfidEventGenerator implements InstructionHandler, NodeControlProvider, SettingSpecifierProvider { /** A prefix added to {@link #getUID()} to form the control ID used. */ public static final String CONTROL_ID_PREFIX = "/rfid/"; /** Topic for when a RFID message has been received. */ public static final String TOPIC_RFID_MESSAGE_RECEIVED = "net/solarnetwork/node/hw/rfid/MESSAGE_RECEIVED"; /** Event parameter for the RFID message value. */ public static final String EVENT_PARAM_MESSAGE = "message"; /** * Event parameter for the RFID message date, as milliseconds since the * epoch. */ public static final String EVENT_PARAM_DATE = "date"; /** Event parameter for the RFID message counter value. */ public static final String EVENT_PARAM_COUNT = "count"; /** Event parameter for the configured {@code uid}. */ public static final String EVENT_PARAM_UID = "uid"; /** Event parameter for the configured {@code groupUID}. */ public static final String EVENT_PARAM_GROUP_UID = "groupUID"; private EventAdmin eventAdmin; private MessageSource messageSource; private String uid = "MockIdTag"; private String groupUID; private final AtomicInteger count = new AtomicInteger(0); @Override public boolean handlesTopic(String topic) { return InstructionHandler.TOPIC_SET_CONTROL_PARAMETER.equals(topic); } @Override public InstructionState processInstruction(Instruction instruction) { // look for a parameter name that matches a control ID InstructionState result = null; final String expectedControlId = CONTROL_ID_PREFIX + uid; for ( String controlId : instruction.getParameterNames() ) { if ( expectedControlId.equals(controlId) ) { // doesn't matter what we try to set the control to, all we do is trigger the event here postRfidScannedEvent(); result = InstructionState.Completed; } } return result; } private void postRfidScannedEvent() { Map<String, Object> props = new HashMap<String, Object>(); props.put(EVENT_PARAM_COUNT, count.incrementAndGet()); props.put(EVENT_PARAM_DATE, System.currentTimeMillis()); props.put(EVENT_PARAM_MESSAGE, uid); props.put(EVENT_PARAM_UID, CONTROL_ID_PREFIX + uid); props.put(EVENT_PARAM_GROUP_UID, groupUID); Event event = new Event(TOPIC_RFID_MESSAGE_RECEIVED, props); EventAdmin ea = eventAdmin; if ( ea != null ) { ea.postEvent(event); } } @Override public List<String> getAvailableControlIds() { return Arrays.asList(CONTROL_ID_PREFIX + uid); } @Override public NodeControlInfo getCurrentControlInfo(String controlId) { if ( controlId == null || !controlId.equals(CONTROL_ID_PREFIX + uid) ) { return null; } NodeControlInfoDatum info = new NodeControlInfoDatum(); info.setCreated(new Date()); info.setSourceId(controlId); info.setType(NodeControlPropertyType.Boolean); info.setReadonly(false); // the control value never changes, just when set to "true" we'll trigger RFID event info.setValue(Boolean.FALSE.toString()); return info; } @Override public String getUID() { return uid; } @Override public String getGroupUID() { return groupUID; } @Override public String getSettingUID() { return "net.solarnetwork.node.hw.rfid.mock"; } @Override public String getDisplayName() { return getClass().getSimpleName(); } @Override public MessageSource getMessageSource() { return messageSource; } @Override public List<SettingSpecifier> getSettingSpecifiers() { MockRfidEventGenerator defaults = new MockRfidEventGenerator(); List<SettingSpecifier> results = new ArrayList<SettingSpecifier>(2); results.add(new BasicTextFieldSettingSpecifier("uid", defaults.uid)); results.add(new BasicTextFieldSettingSpecifier("groupUID", defaults.groupUID)); return results; } public void setEventAdmin(EventAdmin eventAdmin) { this.eventAdmin = eventAdmin; } public void setMessageSource(MessageSource messageSource) { this.messageSource = messageSource; } /** * Set the UID for this RFID scanner, which is also the control ID. * * @param uid * The UID to set. */ public void setUid(String uid) { if ( uid == null ) { return; } this.uid = uid; } /** * Set the group UID to use. * * @param groupUID * The group UID to set. */ public void setGroupUID(String groupUID) { this.groupUID = groupUID; } }