mirror of
https://github.com/meshtastic/python.git
synced 2026-01-07 07:17:56 -05:00
1.1.7
This commit is contained in:
@@ -191,6 +191,16 @@ class MeshInterface:
|
||||
if not noProto:
|
||||
self._startConfig()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
if exc_type is not None and exc_value is not None:
|
||||
logging.error(f'An exception of type {exc_type} with value {exc_value} has occurred')
|
||||
if traceback is not None:
|
||||
logging.error(f'Traceback: {traceback}')
|
||||
self.close()
|
||||
|
||||
def sendText(self, text, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False):
|
||||
"""Send a utf8 string to some other node, if the node has a display it will also be shown on the device.
|
||||
|
||||
@@ -277,6 +287,14 @@ class MeshInterface:
|
||||
self._sendToRadio(toRadio)
|
||||
return meshPacket
|
||||
|
||||
def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')):
|
||||
"""Block until radio config is received. Returns True if config has been received."""
|
||||
for _ in range(int(maxsecs/sleep)):
|
||||
if all(map(lambda a: getattr(self, a, None), attrs)):
|
||||
return True
|
||||
time.sleep(sleep)
|
||||
return False
|
||||
|
||||
def writeConfig(self):
|
||||
"""Write the current (edited) radioConfig to the device"""
|
||||
if self.radioConfig == None:
|
||||
@@ -286,6 +304,55 @@ class MeshInterface:
|
||||
t.set_radio.CopyFrom(self.radioConfig)
|
||||
self._sendToRadio(t)
|
||||
|
||||
def getMyNode(self):
|
||||
if self.myInfo is None:
|
||||
return None
|
||||
myId = self.myInfo.my_node_num
|
||||
for _, nodeDict in self.nodes.items():
|
||||
if 'num' in nodeDict and nodeDict['num'] == myId:
|
||||
if 'user' in nodeDict:
|
||||
return nodeDict['user']
|
||||
return None
|
||||
|
||||
def getLongName(self):
|
||||
user = self.getMyNode()
|
||||
if user is not None:
|
||||
return user.get('longName', None)
|
||||
return None
|
||||
|
||||
def getShortName(self):
|
||||
user = self.getMyNode()
|
||||
if user is not None:
|
||||
return user.get('shortName', None)
|
||||
return None
|
||||
|
||||
def setOwner(self, long_name, short_name=None):
|
||||
"""Set device owner name"""
|
||||
nChars = 3
|
||||
minChars = 2
|
||||
if long_name is not None:
|
||||
long_name = long_name.strip()
|
||||
if short_name is None:
|
||||
words = long_name.split()
|
||||
if len(long_name) <= nChars:
|
||||
short_name = long_name
|
||||
elif len(words) >= minChars:
|
||||
short_name = ''.join(map(lambda word: word[0], words))
|
||||
else:
|
||||
trans = str.maketrans(dict.fromkeys('aeiouAEIOU'))
|
||||
short_name = long_name[0] + long_name[1:].translate(trans)
|
||||
if len(short_name) < nChars:
|
||||
short_name = long_name[:nChars]
|
||||
t = mesh_pb2.ToRadio()
|
||||
if long_name is not None:
|
||||
t.set_owner.long_name = long_name
|
||||
if short_name is not None:
|
||||
short_name = short_name.strip()
|
||||
if len(short_name) > nChars:
|
||||
short_name = short_name[:nChars]
|
||||
t.set_owner.short_name = short_name
|
||||
self._sendToRadio(t)
|
||||
|
||||
@property
|
||||
def channelURL(self):
|
||||
"""The sharable URL that describes the current channel
|
||||
@@ -294,6 +361,19 @@ class MeshInterface:
|
||||
s = base64.urlsafe_b64encode(bytes).decode('ascii')
|
||||
return f"https://www.meshtastic.org/c/#{s}"
|
||||
|
||||
def setURL(self, url, write=True):
|
||||
"""Set mesh network URL"""
|
||||
if self.radioConfig == None:
|
||||
raise Exception("No RadioConfig has been read")
|
||||
|
||||
# URLs are of the form https://www.meshtastic.org/c/#{base64_channel_settings}
|
||||
# Split on '/#' to find the base64 encoded channel settings
|
||||
splitURL = url.split("/#")
|
||||
decodedURL = base64.urlsafe_b64decode(splitURL[-1])
|
||||
self.radioConfig.channel_settings.ParseFromString(decodedURL)
|
||||
if write:
|
||||
self.writeConfig()
|
||||
|
||||
def _generatePacketId(self):
|
||||
"""Get a new unique packet ID"""
|
||||
if self.currentPacketId is None:
|
||||
@@ -357,6 +437,7 @@ class MeshInterface:
|
||||
self._nodesByNum[node["num"]] = node
|
||||
if "user" in node: # Some nodes might not have user/ids assigned yet
|
||||
self.nodes[node["user"]["id"]] = node
|
||||
pub.sendMessage("meshtastic.node.updated", node=node, interface=self)
|
||||
elif fromRadio.config_complete_id == MY_CONFIG_ID:
|
||||
# we ignore the config_complete_id, it is unneeded for our stream API fromRadio.config_complete_id
|
||||
self._connected()
|
||||
@@ -847,6 +928,9 @@ class TCPInterface(StreamInterface):
|
||||
<li><code><a title="meshtastic.MeshInterface.sendPacket" href="#meshtastic.MeshInterface.sendPacket">sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendPosition" href="#meshtastic.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendText" href="#meshtastic.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.setOwner" href="#meshtastic.MeshInterface.setOwner">setOwner</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.setURL" href="#meshtastic.MeshInterface.setURL">setURL</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.waitForConfig" href="#meshtastic.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.writeConfig" href="#meshtastic.MeshInterface.writeConfig">writeConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -885,6 +969,16 @@ debugOut</p>
|
||||
if not noProto:
|
||||
self._startConfig()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
if exc_type is not None and exc_value is not None:
|
||||
logging.error(f'An exception of type {exc_type} with value {exc_value} has occurred')
|
||||
if traceback is not None:
|
||||
logging.error(f'Traceback: {traceback}')
|
||||
self.close()
|
||||
|
||||
def sendText(self, text, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False):
|
||||
"""Send a utf8 string to some other node, if the node has a display it will also be shown on the device.
|
||||
|
||||
@@ -971,6 +1065,14 @@ debugOut</p>
|
||||
self._sendToRadio(toRadio)
|
||||
return meshPacket
|
||||
|
||||
def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')):
|
||||
"""Block until radio config is received. Returns True if config has been received."""
|
||||
for _ in range(int(maxsecs/sleep)):
|
||||
if all(map(lambda a: getattr(self, a, None), attrs)):
|
||||
return True
|
||||
time.sleep(sleep)
|
||||
return False
|
||||
|
||||
def writeConfig(self):
|
||||
"""Write the current (edited) radioConfig to the device"""
|
||||
if self.radioConfig == None:
|
||||
@@ -980,6 +1082,55 @@ debugOut</p>
|
||||
t.set_radio.CopyFrom(self.radioConfig)
|
||||
self._sendToRadio(t)
|
||||
|
||||
def getMyNode(self):
|
||||
if self.myInfo is None:
|
||||
return None
|
||||
myId = self.myInfo.my_node_num
|
||||
for _, nodeDict in self.nodes.items():
|
||||
if 'num' in nodeDict and nodeDict['num'] == myId:
|
||||
if 'user' in nodeDict:
|
||||
return nodeDict['user']
|
||||
return None
|
||||
|
||||
def getLongName(self):
|
||||
user = self.getMyNode()
|
||||
if user is not None:
|
||||
return user.get('longName', None)
|
||||
return None
|
||||
|
||||
def getShortName(self):
|
||||
user = self.getMyNode()
|
||||
if user is not None:
|
||||
return user.get('shortName', None)
|
||||
return None
|
||||
|
||||
def setOwner(self, long_name, short_name=None):
|
||||
"""Set device owner name"""
|
||||
nChars = 3
|
||||
minChars = 2
|
||||
if long_name is not None:
|
||||
long_name = long_name.strip()
|
||||
if short_name is None:
|
||||
words = long_name.split()
|
||||
if len(long_name) <= nChars:
|
||||
short_name = long_name
|
||||
elif len(words) >= minChars:
|
||||
short_name = ''.join(map(lambda word: word[0], words))
|
||||
else:
|
||||
trans = str.maketrans(dict.fromkeys('aeiouAEIOU'))
|
||||
short_name = long_name[0] + long_name[1:].translate(trans)
|
||||
if len(short_name) < nChars:
|
||||
short_name = long_name[:nChars]
|
||||
t = mesh_pb2.ToRadio()
|
||||
if long_name is not None:
|
||||
t.set_owner.long_name = long_name
|
||||
if short_name is not None:
|
||||
short_name = short_name.strip()
|
||||
if len(short_name) > nChars:
|
||||
short_name = short_name[:nChars]
|
||||
t.set_owner.short_name = short_name
|
||||
self._sendToRadio(t)
|
||||
|
||||
@property
|
||||
def channelURL(self):
|
||||
"""The sharable URL that describes the current channel
|
||||
@@ -988,6 +1139,19 @@ debugOut</p>
|
||||
s = base64.urlsafe_b64encode(bytes).decode('ascii')
|
||||
return f"https://www.meshtastic.org/c/#{s}"
|
||||
|
||||
def setURL(self, url, write=True):
|
||||
"""Set mesh network URL"""
|
||||
if self.radioConfig == None:
|
||||
raise Exception("No RadioConfig has been read")
|
||||
|
||||
# URLs are of the form https://www.meshtastic.org/c/#{base64_channel_settings}
|
||||
# Split on '/#' to find the base64 encoded channel settings
|
||||
splitURL = url.split("/#")
|
||||
decodedURL = base64.urlsafe_b64decode(splitURL[-1])
|
||||
self.radioConfig.channel_settings.ParseFromString(decodedURL)
|
||||
if write:
|
||||
self.writeConfig()
|
||||
|
||||
def _generatePacketId(self):
|
||||
"""Get a new unique packet ID"""
|
||||
if self.currentPacketId is None:
|
||||
@@ -1051,6 +1215,7 @@ debugOut</p>
|
||||
self._nodesByNum[node["num"]] = node
|
||||
if "user" in node: # Some nodes might not have user/ids assigned yet
|
||||
self.nodes[node["user"]["id"]] = node
|
||||
pub.sendMessage("meshtastic.node.updated", node=node, interface=self)
|
||||
elif fromRadio.config_complete_id == MY_CONFIG_ID:
|
||||
# we ignore the config_complete_id, it is unneeded for our stream API fromRadio.config_complete_id
|
||||
self._connected()
|
||||
@@ -1190,6 +1355,58 @@ def channelURL(self):
|
||||
</dl>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="meshtastic.MeshInterface.getLongName"><code class="name flex">
|
||||
<span>def <span class="ident">getLongName</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def getLongName(self):
|
||||
user = self.getMyNode()
|
||||
if user is not None:
|
||||
return user.get('longName', None)
|
||||
return None</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.MeshInterface.getMyNode"><code class="name flex">
|
||||
<span>def <span class="ident">getMyNode</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def getMyNode(self):
|
||||
if self.myInfo is None:
|
||||
return None
|
||||
myId = self.myInfo.my_node_num
|
||||
for _, nodeDict in self.nodes.items():
|
||||
if 'num' in nodeDict and nodeDict['num'] == myId:
|
||||
if 'user' in nodeDict:
|
||||
return nodeDict['user']
|
||||
return None</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.MeshInterface.getShortName"><code class="name flex">
|
||||
<span>def <span class="ident">getShortName</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def getShortName(self):
|
||||
user = self.getMyNode()
|
||||
if user is not None:
|
||||
return user.get('shortName', None)
|
||||
return None</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.MeshInterface.sendData"><code class="name flex">
|
||||
<span>def <span class="ident">sendData</span></span>(<span>self, byteData, destinationId='^all', dataType=0, wantAck=False, wantResponse=False)</span>
|
||||
</code></dt>
|
||||
@@ -1332,6 +1549,84 @@ wantAck – True if you want the message sent in a reliable manner (with ret
|
||||
dataType=mesh_pb2.Data.CLEAR_TEXT, wantAck=wantAck, wantResponse=wantResponse)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.MeshInterface.setOwner"><code class="name flex">
|
||||
<span>def <span class="ident">setOwner</span></span>(<span>self, long_name, short_name=None)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Set device owner name</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def setOwner(self, long_name, short_name=None):
|
||||
"""Set device owner name"""
|
||||
nChars = 3
|
||||
minChars = 2
|
||||
if long_name is not None:
|
||||
long_name = long_name.strip()
|
||||
if short_name is None:
|
||||
words = long_name.split()
|
||||
if len(long_name) <= nChars:
|
||||
short_name = long_name
|
||||
elif len(words) >= minChars:
|
||||
short_name = ''.join(map(lambda word: word[0], words))
|
||||
else:
|
||||
trans = str.maketrans(dict.fromkeys('aeiouAEIOU'))
|
||||
short_name = long_name[0] + long_name[1:].translate(trans)
|
||||
if len(short_name) < nChars:
|
||||
short_name = long_name[:nChars]
|
||||
t = mesh_pb2.ToRadio()
|
||||
if long_name is not None:
|
||||
t.set_owner.long_name = long_name
|
||||
if short_name is not None:
|
||||
short_name = short_name.strip()
|
||||
if len(short_name) > nChars:
|
||||
short_name = short_name[:nChars]
|
||||
t.set_owner.short_name = short_name
|
||||
self._sendToRadio(t)</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.MeshInterface.setURL"><code class="name flex">
|
||||
<span>def <span class="ident">setURL</span></span>(<span>self, url, write=True)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Set mesh network URL</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def setURL(self, url, write=True):
|
||||
"""Set mesh network URL"""
|
||||
if self.radioConfig == None:
|
||||
raise Exception("No RadioConfig has been read")
|
||||
|
||||
# URLs are of the form https://www.meshtastic.org/c/#{base64_channel_settings}
|
||||
# Split on '/#' to find the base64 encoded channel settings
|
||||
splitURL = url.split("/#")
|
||||
decodedURL = base64.urlsafe_b64decode(splitURL[-1])
|
||||
self.radioConfig.channel_settings.ParseFromString(decodedURL)
|
||||
if write:
|
||||
self.writeConfig()</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.MeshInterface.waitForConfig"><code class="name flex">
|
||||
<span>def <span class="ident">waitForConfig</span></span>(<span>self, sleep=0.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig'))</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<div class="desc"><p>Block until radio config is received. Returns True if config has been received.</p></div>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')):
|
||||
"""Block until radio config is received. Returns True if config has been received."""
|
||||
for _ in range(int(maxsecs/sleep)):
|
||||
if all(map(lambda a: getattr(self, a, None), attrs)):
|
||||
return True
|
||||
time.sleep(sleep)
|
||||
return False</code></pre>
|
||||
</details>
|
||||
</dd>
|
||||
<dt id="meshtastic.MeshInterface.writeConfig"><code class="name flex">
|
||||
<span>def <span class="ident">writeConfig</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
@@ -1433,6 +1728,9 @@ debugOut {stream} – If a stream is provided, any debug serial output from
|
||||
<li><code><a title="meshtastic.StreamInterface.sendPacket" href="#meshtastic.MeshInterface.sendPacket">sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.sendPosition" href="#meshtastic.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.sendText" href="#meshtastic.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.setOwner" href="#meshtastic.MeshInterface.setOwner">setOwner</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.setURL" href="#meshtastic.MeshInterface.setURL">setURL</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.waitForConfig" href="#meshtastic.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.writeConfig" href="#meshtastic.MeshInterface.writeConfig">writeConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -1652,6 +1950,9 @@ start the reading thread later.</p></div>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendPacket" href="#meshtastic.MeshInterface.sendPacket">sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendPosition" href="#meshtastic.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendText" href="#meshtastic.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.setOwner" href="#meshtastic.MeshInterface.setOwner">setOwner</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.setURL" href="#meshtastic.MeshInterface.setURL">setURL</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.waitForConfig" href="#meshtastic.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.writeConfig" href="#meshtastic.MeshInterface.writeConfig">writeConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -1725,6 +2026,9 @@ hostname {string} – Hostname/IP address of the device to connect to</p></d
|
||||
<li><code><a title="meshtastic.StreamInterface.sendPacket" href="#meshtastic.MeshInterface.sendPacket">sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.sendPosition" href="#meshtastic.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.sendText" href="#meshtastic.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.setOwner" href="#meshtastic.MeshInterface.setOwner">setOwner</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.setURL" href="#meshtastic.MeshInterface.setURL">setURL</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.waitForConfig" href="#meshtastic.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.StreamInterface.writeConfig" href="#meshtastic.MeshInterface.writeConfig">writeConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -1768,10 +2072,16 @@ hostname {string} – Hostname/IP address of the device to connect to</p></d
|
||||
<h4><code><a title="meshtastic.MeshInterface" href="#meshtastic.MeshInterface">MeshInterface</a></code></h4>
|
||||
<ul class="two-column">
|
||||
<li><code><a title="meshtastic.MeshInterface.channelURL" href="#meshtastic.MeshInterface.channelURL">channelURL</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.getLongName" href="#meshtastic.MeshInterface.getLongName">getLongName</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.getMyNode" href="#meshtastic.MeshInterface.getMyNode">getMyNode</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.getShortName" href="#meshtastic.MeshInterface.getShortName">getShortName</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendData" href="#meshtastic.MeshInterface.sendData">sendData</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendPacket" href="#meshtastic.MeshInterface.sendPacket">sendPacket</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendPosition" href="#meshtastic.MeshInterface.sendPosition">sendPosition</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.sendText" href="#meshtastic.MeshInterface.sendText">sendText</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.setOwner" href="#meshtastic.MeshInterface.setOwner">setOwner</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.setURL" href="#meshtastic.MeshInterface.setURL">setURL</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.waitForConfig" href="#meshtastic.MeshInterface.waitForConfig">waitForConfig</a></code></li>
|
||||
<li><code><a title="meshtastic.MeshInterface.writeConfig" href="#meshtastic.MeshInterface.writeConfig">writeConfig</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
2
setup.py
2
setup.py
@@ -12,7 +12,7 @@ with open("README.md", "r") as fh:
|
||||
# This call to setup() does all the work
|
||||
setup(
|
||||
name="meshtastic",
|
||||
version="1.1.6",
|
||||
version="1.1.7",
|
||||
description="Python API & client shell for talking to Meshtastic devices",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
|
||||
Reference in New Issue
Block a user