private static PdmMessage bolus_message(ushort pulse_count, int pulse_speed = 16, int delivery_delay = 2) { var commandBody = new Bytes().Append(0x02); var bodyForChecksum = new Bytes().Append(0x01); var pulse_span = (ushort)(pulse_speed * pulse_count); bodyForChecksum.Append(pulse_span); bodyForChecksum.Append(pulse_count); bodyForChecksum.Append(pulse_count); var checksum = getChecksum(bodyForChecksum); commandBody.Append(checksum); commandBody.Append(bodyForChecksum); var msg = new PdmMessage(PdmRequest.InsulinSchedule, commandBody); commandBody = new Bytes().Append(0x00); ushort p10 = (ushort)(pulse_count * 10); commandBody.Append(p10); uint dd = (uint)delivery_delay * (uint)100000; commandBody.Append(dd); commandBody.Append(new byte[] { 0, 0, 0, 0, 0, 0 }); msg.add_part(PdmRequest.BolusSchedule, commandBody); return(msg); }
public static PdmMessage request_temp_basal(decimal basal_rate_iuhr, decimal duration_hours) { var half_hour_count = (int)(duration_hours * 2.0m); var hh_units = new decimal[half_hour_count]; for (int i = 0; i < half_hour_count; i++) { hh_units[i] = basal_rate_iuhr / 2.0m; } var pulseList = getPulsesForHalfHours(hh_units); var iseList = getInsulinScheduleTableFromPulses(pulseList); var iseBody = getBodyFromTable(iseList); var pulseBody = getBodyFromTable(pulseList); var cmd_body = new Bytes(); cmd_body.Append(0x01); var body_checksum = new Bytes(); body_checksum.Append((byte)half_hour_count); ushort b1 = 0x3840; body_checksum.Append(b1); body_checksum.Append(pulseList[0]); var checksum = getChecksum(new Bytes(body_checksum, pulseBody)); cmd_body.Append(checksum); cmd_body.Append(body_checksum); cmd_body.Append(iseBody); var msg = new PdmMessage(PdmRequest.InsulinSchedule, cmd_body); byte reminders = 0; //#if confidenceReminder: //# reminders |= 0x40 cmd_body = new Bytes(); cmd_body.Append(reminders).Append(0x00); var pulseEntries = getPulseIntervalEntries(hh_units); var firstPte = pulseEntries[0]; cmd_body.Append(firstPte.Item1); cmd_body.Append(firstPte.Item2); foreach (var pte in pulseEntries) { cmd_body.Append(pte.Item1); cmd_body.Append(pte.Item2); } msg.add_part(PdmRequest.TempBasalSchedule, cmd_body); return(msg); }
public Bytes get_data() { var data = new Bytes().Append(this.address); data.Append((byte)((int)this.type | this.sequence)); data.Append(this.body); data.Append(CrcUtil.Crc8(data.ToArray())); return(data); }
public static PdmMessage request_setup_pod(uint lot, uint tid, uint address, int year, byte month, byte day, byte hour, byte minute) { var cmd_body = new Bytes(); cmd_body.Append(address); cmd_body.Append(new byte[] { 0x14, 0x04 }); cmd_body.Append(new byte[] { month, day, (byte)(year - 2000), hour, minute }); cmd_body.Append(lot); cmd_body.Append(tid); return(new PdmMessage(PdmRequest.SetupPod, cmd_body)); }
public async Task <Bytes> GetPacket(uint timeout = 5000) { try { await Connect(); var cmdParams = new Bytes((byte)0); cmdParams.Append(timeout); var result = await this.SendCommand(RileyLinkCommandType.SendAndListen, cmdParams, (int)timeout + 500); if (result != null) { return(result.Sub(0, 2).Append(Manchester.Decode(result.Sub(2).ToArray()))); } else { return(null); } } catch (OmnipyException) { throw; } catch (Exception e) { throw new PacketRadioException("Error while receiving data with RL", e); } }
public async Task SendPacket(Bytes packet, byte repeat_count, ushort delay_ms, ushort preamble_ext_ms) { try { await Connect(); Debug.WriteLine($"SEND radio packet: {packet}"); var data = Manchester.Encode(packet.ToArray()); var cmdParams = new Bytes((byte)0).Append(repeat_count); cmdParams.Append(delay_ms); cmdParams.Append(preamble_ext_ms); cmdParams.Append(data); await this.SendCommand(RileyLinkCommandType.SendAndListen, cmdParams, 30000); } catch (OmnipyException) { throw; } catch (Exception e) { throw new PacketRadioException("Error while sending data with RL", e); } }
public List <Packet> get_radio_packets(int first_packet_sequence) { this.message_str_prefix = $"{this.address:%08X} {this.sequence:%02X} {this.expect_critical_followup} "; var message_body_len = 0; foreach (var p in this.parts) { var cmd_body = p.Item2; var nonce = p.Item3; message_body_len += (int)cmd_body.Length + 2; if (nonce != null) { message_body_len += 4; } } byte b0 = 0; if (this.expect_critical_followup) { b0 = 0x80; } b0 |= (byte)(this.sequence << 2); b0 |= (byte)((message_body_len >> 8) & 0x03); byte b1 = (byte)(message_body_len & 0xff); var message_body = new Bytes(this.address.Value); message_body.Append(b0); message_body.Append(b1); foreach (var p in this.parts) { var cmd_type = p.Item1; var cmd_body = p.Item2; var nonce = p.Item3; if (nonce == null) { if (cmd_type == (byte)PodResponse.Status) { message_body.Append(cmd_type); } else { message_body.Append(cmd_type); message_body.Append((byte)cmd_body.Length); } } else { message_body.Append(cmd_type); message_body.Append((byte)(cmd_body.Length + 4)); message_body.Append(nonce.Value); } message_body.Append(cmd_body[0]); } var crc_calculated = CrcUtil.Crc16(message_body.ToArray()); message_body.Append(crc_calculated); int index = 0; bool first_packet = true; int sequence = first_packet_sequence; int total_body_len = (int)message_body.Length; var radio_packets = new List <Packet>(); while (index < message_body.Length) { var to_write = Math.Min(31, message_body.Length - index); var packet_body = message_body.Sub(index, index + to_write); radio_packets.Add(new Packet(AckAddressOverride.Value, first_packet ? this.type.Value : RadioPacketType.CON, sequence, packet_body)); first_packet = false; sequence = (sequence + 2) % 32; index += to_write; } if (this.DoubleTake) { var fp = radio_packets[0]; radio_packets.Insert(0, fp); } return(radio_packets); }
public static PdmMessage request_set_basal_schedule(decimal[] schedule, ushort hour, ushort minute, ushort second) { var halved_schedule = new decimal[48]; for (int i = 0; i < 47; i++) { halved_schedule[i] = schedule[i] / 2m; } int current_hh = hour * 2; ushort seconds_past_hh = 0; if (minute < 30) { seconds_past_hh = (ushort)(minute * 60 + second); } else { seconds_past_hh = (ushort)((minute - 30) * 60 + second); } var seconds_to_hh = (ushort)(1800 - seconds_past_hh); var seconds_to_hh8 = (ushort)(seconds_to_hh * 8); var pulse_list = getPulsesForHalfHours(halved_schedule); var ise_list = getInsulinScheduleTableFromPulses(pulse_list); var ise_body = getBodyFromTable(ise_list); var pulse_body = getBodyFromTable(pulse_list); var command_body = new Bytes(0); var body_checksum = new Bytes((byte)current_hh); var current_hh_pulse_count = pulse_list[current_hh]; var remaining_pulse_count = (ushort)(current_hh_pulse_count * seconds_to_hh / 1800); body_checksum.Append(seconds_to_hh8); body_checksum.Append(remaining_pulse_count); command_body.Append(getChecksum(new Bytes(body_checksum, pulse_body))); command_body.Append(body_checksum); command_body.Append(ise_body); var msg = new PdmMessage(PdmRequest.InsulinSchedule, command_body); command_body = new Bytes(new byte[] { 0, 0 }); var pulse_entries = getPulseIntervalEntries(halved_schedule); for (int i = 0; i < pulse_entries.Length; i++) { var pti = pulse_entries[i]; var pulses10 = pti.Item1; var interval = pti.Item2; var indices = pti.Item3; var ii = Array.IndexOf <int>(indices, current_hh); if (ii >= 0) { command_body.Append((byte)i); var pulses_past_intervals = (ushort)((uint)ii * (uint)1800000000 / (uint)interval); var pulses_past_this_interval = (ushort)((uint)seconds_past_hh * (uint)1000000 / (uint)interval + 1); var remaining_pulses_this_interval = (ushort)(pulses10 - pulses_past_this_interval - pulses_past_intervals); var microseconds_to_next_interval = (uint)interval - ((uint)seconds_past_hh * (uint)1000000 % (uint)interval); command_body.Append(remaining_pulses_this_interval); command_body.Append(microseconds_to_next_interval); break; } } for (int i = 0; i < pulse_entries.Length; i++) { var pti = pulse_entries[i]; var pulses10 = pti.Item1; var interval = pti.Item2; command_body.Append(pulses10); command_body.Append(interval); } msg.add_part(PdmRequest.BasalSchedule, command_body); return(msg); }
public static PdmMessage request_alert_setup(List <AlertConfiguration> alert_configurations) { var cmd_body = new Bytes(); foreach (var ac in alert_configurations) { if (ac.alert_after_minutes == null && ac.alert_after_reservoir == null && ac.activate) { throw new PdmException("Either alert_after_minutes or alert_after_reservoir must be set"); } else if (ac.alert_after_minutes != null && ac.alert_after_reservoir != null) { throw new PdmException("Only one of alert_after_minutes or alert_after_reservoir must be set"); } if (ac.alert_duration > 0x1FF) { throw new PdmException($"Alert duration in minutes cannot be more than {0x1ff:%d}"); } else if (ac.alert_duration < 0) { throw new PdmException("Invalid alert duration value"); } if (ac.alert_after_minutes != null && ac.alert_after_minutes > 4800) { throw new PdmException("Alert cannot be set beyond 80 hours"); } if (ac.alert_after_minutes != null && ac.alert_after_minutes < 0) { throw new PdmException("Invalid value for alert_after_minutes"); } if (ac.alert_after_reservoir != null && ac.alert_after_reservoir > 50) { throw new PdmException("Alert cannot be set for more than 50 units"); } if (ac.alert_after_reservoir != null && ac.alert_after_reservoir < 0) { throw new PdmException("Invalid value for alert_after_reservoir"); } byte b0 = (byte)(ac.alert_index << 4); if (ac.activate) { b0 |= 0x08; } if (ac.alert_after_reservoir != null) { b0 |= 0x04; } if (ac.trigger_auto_off) { b0 |= 0x02; } b0 |= (byte)((ac.alert_duration >> 8) & 0x01); byte b1 = (byte)(ac.alert_duration & 0x00ff); byte b2 = 0; byte b3 = 0; if (ac.alert_after_reservoir != null) { var reservoir_limit = (int)(ac.alert_after_reservoir * 10); b2 = (byte)(reservoir_limit >> 8); b3 = (byte)(reservoir_limit & 0xff); } if (ac.alert_after_minutes != null) { b2 = (byte)(ac.alert_after_minutes >> 8); b3 = (byte)(ac.alert_after_minutes & 0xff); } cmd_body.Append(new byte[] { b0, b1, b2, b3, (byte)ac.beep_repeat_type, (byte)ac.beep_type }); } return(new PdmMessage(PdmRequest.ConfigureAlerts, cmd_body)); }