package cc.blynk.server.hardware.handlers.hardware.logic; import cc.blynk.server.core.model.DashBoard; import cc.blynk.server.core.model.Pin; import cc.blynk.server.core.model.PinStorageKey; import cc.blynk.server.core.model.enums.PinType; import cc.blynk.server.core.model.widgets.HardwareSyncWidget; import cc.blynk.server.core.model.widgets.Widget; import cc.blynk.server.core.model.widgets.others.rtc.RTC; import cc.blynk.server.core.protocol.enums.Response; import cc.blynk.server.core.protocol.model.messages.StringMessage; import cc.blynk.server.core.session.HardwareStateHolder; import cc.blynk.utils.ParseUtil; import cc.blynk.utils.PinUtil; import cc.blynk.utils.StringUtils; import io.netty.channel.ChannelHandlerContext; import java.util.Map; import static cc.blynk.server.core.protocol.enums.Command.HARDWARE; import static cc.blynk.utils.BlynkByteBufUtil.makeResponse; import static cc.blynk.utils.BlynkByteBufUtil.makeUTF8StringMessage; /** * The Blynk Project. * Created by Dmitriy Dumanskiy. * Created on 2/1/2015. * */ public class HardwareSyncLogic { public static void messageReceived(ChannelHandlerContext ctx, HardwareStateHolder state, StringMessage message) { final int dashId = state.dashId; final int deviceId = state.deviceId; DashBoard dash = state.user.profile.getDashByIdOrThrow(dashId); if (message.length == 0) { syncAll(ctx, message.id, dash, deviceId); } else { syncSpecificPins(ctx, message.body, message.id, dash, deviceId); } } private static void syncAll(ChannelHandlerContext ctx, int msgId, DashBoard dash, int deviceId) { //return all widgets state for (Widget widget : dash.widgets) { //one exclusion, no need to sync RTC if (widget instanceof HardwareSyncWidget && !(widget instanceof RTC)) { ((HardwareSyncWidget) widget).sendHardSync(ctx, msgId, deviceId); } } //return all static server holders for (Map.Entry<PinStorageKey, String> entry : dash.pinsStorage.entrySet()) { PinStorageKey key = entry.getKey(); if (deviceId == key.deviceId) { String body = Pin.makeHardwareBody(key.pinType, key.pin, entry.getValue()); ctx.write(makeUTF8StringMessage(HARDWARE, msgId, body), ctx.voidPromise()); } } ctx.flush(); } //message format is "vr 22 33" //return specific widget state private static void syncSpecificPins(ChannelHandlerContext ctx, String messageBody, int msgId, DashBoard dash, int deviceId) { String[] bodyParts = messageBody.split(StringUtils.BODY_SEPARATOR_STRING); if (bodyParts.length < 2 || bodyParts[0].isEmpty()) { ctx.writeAndFlush(makeResponse(msgId, Response.ILLEGAL_COMMAND), ctx.voidPromise()); return; } PinType pinType = PinType.getPinType(bodyParts[0].charAt(0)); if (PinUtil.isReadOperation(bodyParts[0])) { for (int i = 1; i < bodyParts.length; i++) { byte pin = ParseUtil.parseByte(bodyParts[i]); Widget widget = dash.findWidgetByPin(deviceId, pin, pinType); if (widget == null) { String value = dash.pinsStorage.get(new PinStorageKey(deviceId, pinType, pin)); if (value != null) { String body = Pin.makeHardwareBody(pinType, pin, value); ctx.write(makeUTF8StringMessage(HARDWARE, msgId, body), ctx.voidPromise()); } } else if (widget instanceof HardwareSyncWidget) { ((HardwareSyncWidget) widget).sendHardSync(ctx, msgId, deviceId); } } ctx.flush(); } } }