1 module finedge.ext.connectors; 2 3 import haystack.tag; 4 import haystack.filter; 5 import std.typecons; 6 import std.conv; 7 import std.array; 8 import std.range; 9 import core.time; 10 11 export: 12 shared interface ConnContext 13 { 14 @property shared(IIntegratedConnectorImpl) conn(); 15 @property immutable(Dict) record(); 16 @property immutable(TuningPolicy) tuningPolicy(); 17 //@property shared(TagDatabase) db(); 18 void * callSharedMethod(string extName, string methodName, shared(void*)[] args...); 19 } 20 21 shared interface ExtensionLibrary 22 { 23 void * callFunction(string name, shared(void*)[] args...); 24 } 25 26 immutable struct TuningPolicy 27 { 28 Dict record; 29 string name = "default"; 30 Duration pollInterval = dur!("seconds")(1); 31 Duration staleExpiration = dur!("minutes")(5); 32 Duration maxWriteInterval; 33 Duration minWriteInterval; 34 35 private this(immutable(Dict) record) 36 { 37 this.record = record; 38 this.name = record.get!Str("name").val; 39 40 if (record.has("pollTime")) 41 this.pollInterval = dur!("seconds")(cast (long) record.get!Num("pollTime").val); 42 43 if (record.has("staleTime")) 44 this.staleExpiration = dur!("seconds")(cast (long) record.get!Num("staleTime").val); 45 46 if (record.has("maxWriteTime")) 47 this.maxWriteInterval = dur!("seconds")(cast (long) record.get!Num("maxWriteTime").val); 48 49 if (record.has("minWriteTime")) 50 this.minWriteInterval = dur!("seconds")(cast (long) record.get!Num("minWriteTime").val); 51 } 52 53 @property bool hasMinWrite() 54 { 55 return (this.minWriteInterval != Duration.init); 56 } 57 58 @property bool hasMaxWrite() 59 { 60 return (this.maxWriteInterval != Duration.init); 61 } 62 63 @property immutable(Ref) id() 64 { 65 if (this.record == Dict.init) 66 return Ref.init; 67 68 return this.record.id; 69 } 70 71 static TuningPolicy fromRec(immutable(Dict) record) 72 { 73 return TuningPolicy(record); 74 } 75 } 76 77 78 shared abstract class ExtensionConnector 79 { 80 protected shared(ConnContext) context; 81 82 void setContext(shared(ConnContext) context) 83 { 84 this.context = context; 85 } 86 87 abstract immutable(Dict) onOpen(); 88 abstract void onClose(); 89 abstract void onPoll(); 90 abstract void onWrite(shared(ConnPoint) point, Tag value, int level, string who); 91 abstract immutable(Grid) onLearn(Tag token = Na()); 92 abstract void onPointChange(shared(ConnPoint) point, immutable(Dict) changes); 93 abstract void onWatch(shared(ConnPoint)[] points); 94 abstract void onUnwatch(shared(ConnPoint)[] points); 95 abstract void onHouseKeeping(); 96 abstract void onShutdown(); 97 98 99 final void open() 100 { 101 this.context.conn.send(ConnMsg.make("open")); 102 } 103 104 final void openPin(string name) 105 { 106 this.context.conn.send(ConnMsg.make("open", Str(name).tag)); 107 } 108 109 final void close() 110 { 111 this.context.conn.send(ConnMsg.make("close")); 112 } 113 114 final void closePin(string name) 115 { 116 this.context.conn.send(ConnMsg.make("close", Str(name).tag)); 117 } 118 } 119 120 shared abstract class NativeEdgeExtension : EdgeExtensionImpl 121 { 122 // TODO: Make DB query and commit aliases. So that the extension can manipulate the db 123 } 124 125 shared interface EdgeExtensionImpl 126 { 127 void onStart(); 128 void onStop(); 129 void onEnable(); 130 void onDisable(); 131 void onUnload(); 132 void onChange(immutable(Dict) changes); 133 immutable(Grid) onDiscover(Tag params = Tag.init); 134 } 135 136 shared interface IIntegratedConnectorImpl 137 { 138 @property immutable(Dict) record(); 139 @property immutable(TuningPolicy) tuningPolicy(); 140 @property shared(ConnPoint)[] watchedPoints(); 141 @property shared(ConnPoint[Ref]) pointTable(); 142 @property bool isOpen(); 143 void send(immutable(ConnMsg) message); 144 145 } 146 147 shared interface ConnPoint 148 { 149 enum Status {unknown, ok, overridden, stale, fault, down} 150 151 @property Ref id(); 152 @property Status currentStatus(); 153 @property Status writeStatus(); 154 @property Tag currentValue(); 155 @property int currentPriority(); 156 @property Tag[] priorityArray(); 157 @property MonoTime lastReadTime(); 158 @property MonoTime lastWriteTime(); 159 @property shared(Dict) rec(); 160 void refreshRecord(); 161 162 void updateWriteError(Error error); 163 void updateReadError(Error error); 164 void updateWriteOk(immutable(Tag) value, int priority); 165 void updateReadOk(immutable(Tag) value, int priority); 166 } 167 168 immutable class ConnMsg 169 { 170 string name; 171 Tag[] data; 172 173 this(string name) 174 { 175 this.name = name; 176 this.data = null; 177 } 178 179 this(string name, immutable(Tag)[] data) 180 { 181 this.name = name; 182 this.data = data; 183 } 184 185 bool hasData() 186 { 187 return (this.data !is null); 188 } 189 190 public static immutable(ConnMsg) make(string name) 191 { 192 return new immutable ConnMsg(name); 193 } 194 195 196 public static immutable(ConnMsg) make(string name, immutable(Tag)[] data) 197 { 198 return new immutable ConnMsg(name, data); 199 } 200 201 public static immutable(ConnMsg) make(string name, immutable(Tag) data) 202 { 203 return new immutable ConnMsg(name, [data]); 204 } 205 }